Рейтинговые книги
Читем онлайн C# 4.0: полное руководство - Герберт Шилдт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 58 59 60 61 62 63 64 65 66 ... 294

// Класс для хранения символов в стеке.

using System;

class Stack {

  // Эти члены класса являются закрытыми,

  char[] stck; // массив, содержащий стек

  int tos;    // индекс вершины стека

  // Сконструировать пустой объект класса Stack по заданному размеру стека,

  public Stack(int size) {

    stck = new char[size]; // распределить память для стека

    tos = 0;

  }

  // Сконструировать объект класса Stack из существующего стека,

  public Stack(Stack ob) {

    // Распределить память для стека,

    stck = new char[ob.stck.Length];

    // Скопировать элементы в новый стек,

    for (int i=0; i < ob.tos; i++)

      stck[i] = ob.stck[i];

    // Установить переменную tos для нового стека,

    tos = ob.tos;

  }

  // Поместить символы в стек,

  public void Push(char ch) {

    if(tos==stck.Length) {

      Console.WriteLine(" - Стек заполнен.");

      return;

    }

    stck[tos] = ch;

    tos++;

  }

  // Извлечь символ из стека,

  public char Pop() {

    if(tos==0) {

      Console.WriteLine (" - Стек пуст.");

      return (char) 0;

    }

    tos--;

    return stck[tos];

  }

  // Возвратить значение true, если стек заполнен,

  public bool IsFull() {

    return tos==stck.Length;

  }

  // Возвратить значение true, если стек пуст,

  public bool IsEmpty() {

    return tos==0;

  }

  // Возвратить общую емкость стека,

  public int Capacity()    {

    return stck.Length;

  }

  // Возвратить количество объектов, находящихся в настоящий момент в стеке,

  public int GetNum() {

    return tos;

  }

}

// Продемонстрировать применение класса Stack.

class StackDemo {

  static void Main() {

    Stack stk1 = new Stack(10);

    char ch;

    int i;

    // Поместить ряд символов в стек stk1.

    Console.WriteLine("Поместить символы А-J в стек stk1.");

    for(i=0; !stk1.IsFull(); i++)

      stk1.Push((char) ('A' + i));

    // Создать копию стека stck1.

    Stack stk2 = new Stack(stk1);

    // Вывести содержимое стека stk1.

    Console.Write("Содержимое стека stk1: ");

    while ( !stk1.IsEmpty() ) {

      ch = stk1.Pop();

      Console.Write(ch);

    }

    Console.WriteLine();

    Console.Write("Содержимое стека stk2: ");

    while ( !stk2.IsEmpty() ) {

      ch = stk2.Pop();

      Console.Write(ch);

    }

    Console.WriteLine ("n");

  }

}

Результат выполнения этой программы приведен ниже.

Поместить символы А-J в стек stk1.

Содержимое стека stk1: JIHGFEDCBA

Содержимое стека stk2: JIHGFEDCBA

В классе StackDemo сначала конструируется первый стек (stk1), заполняемый символами. Затем этот стек используется, для конструирования второго стека (stk2). Это приводит к выполнению следующего конструктора класса Stack.

// Сконструировать объект класса Stack из существующего стека,

public Stack(Stack ob) {

  // Распределить память для стека,

  stck = new char[ob.stck.Length];

  // Скопировать элементы в новый стек,

  for (int i=0; i < ob.tos; i++)

    stck[i] = ob.stck[i];

  // Установить переменную tos для нового стека,

  tos = ob.tos;

}

В этом конструкторе сначала распределяется достаточный объем памяти для массива, чтобы хранить в нем элементы стека, передаваемого в качестве аргумента ob. Затем содержимое массива, образующего стек ob, копируется в новый массив, после чего соответственно устанавливается переменная tos, содержащая индекс вершины стека. По завершении работы конструктора новый и исходный стеки существуют как отдельные, хотя и одинаковые объекты.

Вызов перегружаемого конструктора с помощью ключевого слова this

Когда приходится работать с перегружаемыми конструкторами, то иногда очень полезно предоставить возможность одному конструктору вызывать другой. В C# это дается с помощью ключевого слова this. Ниже приведена общая форма такого вызова.

имя_конструктора{список_параметров1) : this (список_параметров2) {

// ... Тело конструктора, которое может быть пустым.

}

В исходном конструкторе сначала выполняется перегружаемый конструктор, список параметров которого соответствует критерию список_параметров2, а затем все остальные операторы, если таковые имеются в исходном конструкторе. Ниже приведен соответствующий пример.

// Продемонстрировать вызов конструктора с помощью ключевого слова this.

using System;

class XYCoord {

  public int x, y;

  public XYCoord() : this(0, 0) {

    Console.WriteLine("В конструкторе XYCoord()");

  }

  public XYCoord(XYCoord obj) : this(obj.x, obj.y) {

    Console.WriteLine("В конструкторе XYCoord(obj)");

  }

  public XYCoord(int i, int j) {

    Console.WriteLine("В конструкторе XYCoord(int, int)"); x = i;

    y = j;

  }

}

class OverloadConsDemo {

  static void Main() {

    XYCoord tl = new XYCoord();

    XYCoord t2 = new XYCoord(8, 9);

    XYCoord t3 = new XYCoord(t2);

    Console.WriteLine("tl.x,tl.y:" + tl.x + ", " + tl.y);

    Console.WriteLine("t2.x,t2.y:" + t2.x + ", " + t2.y);

    Console.WriteLine("t3.x,t3.y:" + t3.x + ", " + t3.y);

  }

}

Выполнение этого кода приводит к следующему результату.

В конструкторе XYCoord(int, int)

В конструкторе XYCoord()

В конструкторе XYCoord(int, int)

В конструкторе XYCoord(int, int)

В конструкторе XYCoord(obj)

tl.x, tl.y: 0, 0

t2.x, t2.у: 8, 9

t3.x, t3.у: 8, 9

Код в приведенном выше примере работает следующим образом. Единственным конструктором, фактически инициализирующим поля х и у в классе XYCoord, является конструктор XYCoord(int, int).А два других конструктора просто вызывают этот конструктор с помощью ключевого слова this. Например, когда создается объект t1, то вызывается его конструктор XYCoord(), что приводит к вызову this(0, 0), который в данном случае преобразуется в вызов конструктора XYCoord(0, 0). То же самое происходит и при создании объекта t2.

Вызывать перегружаемый конструктор с помощью ключевого слова this полезно, в частности, потому, что он позволяет исключить ненужное дублирование кода. В приведенном выше примере нет никакой необходимости дублировать во всех трех конструкторах одну и ту же последовательность инициализации, и благодаря применению ключевого слова this такое дублирование исключается. Другое преимущество организации подобного вызова перезагружаемого конструктора заключается в возможности создавать конструкторы с задаваемыми "по умолчанию" аргументами, когда эти аргументы не указаны явно. Ниже приведен пример создания еще одного конструктора XYCoord.

1 ... 58 59 60 61 62 63 64 65 66 ... 294
На этой странице вы можете бесплатно читать книгу C# 4.0: полное руководство - Герберт Шилдт бесплатно.
Похожие на C# 4.0: полное руководство - Герберт Шилдт книги

Оставить комментарий