Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подробнее о методах и классах.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
144 Кб
Скачать
☆

8.7 Перегрузка конструкторов

Как и методы, конструкторы также могут перегружаться. Это дает возможность конструировать объекты самыми разными способами. В качестве примера рассмотрим следующую программу.

Листинг 8.20

// Продемонстрировать перегрузку конструктора.

using System;

class MyClass

{

public int x;

public MyClass()

{

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

x = 0;

}

public MyClass(int i)

{

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

x = i;

}

public MyClass(double d)

{

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

x = (int) d;

}

public MyClass(int i, int j)

{

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

x = i * j;

}

}

class OverloadConsDemo

{

static void Main()

{

MyClass t1 = new MyClass();

MyClass t2 = new MyClass(88);

MyClass t3 = new MyClass(17.23);

MyClass t4 = new MyClass(2, 4);

Console.WriteLine("t1.x: " + t1.x);

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

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

Console.WriteLine("t4.x: " + t4.x);

}

}

При выполнении этой программы получается следующий результат.

В конструкторе MyClass().

В конструкторе MyClass (int).

В конструкторе MyClass(double).

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

tl.x: 0

t2.x: 88

t3.x: 17

t4.x: 8

В данном примере конструктор MyClass() перегружается четыре раза, всякий раз конструируя объект по-разному. Подходящий конструктор вызывается каждый раз, исходя из аргументов, указываемых при выполнении оператора new. Перегрузка кон­структора класса предоставляет пользователю этого класса дополнительные преиму­щества в конструировании объектов.

Одна из самых распространенных причин для перегрузки конструкторов заключа­ется в необходимости предоставить возможность одним объектам инициализировать другие. В качестве примера ниже приведен усовершенствованный вариант разработан­ного ранее класса Stack, позволяющий конструировать один стек из другого.

Листинг 8.21

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

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("Поместить симвоы A-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");

}

}

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

Поместить символы A-J в стек stkl.

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

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

В классе StackDemo сначала конструируется первый стек (stkl), заполняемый символами. Затем этот стек используется, для конструирования второго стека (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, содержащая индекс вершины стека. По завершении работы конструктора новый и исходный стеки существуют как отдель­ные, хотя и одинаковые объекты.