Программирование >>  Дополнительные возможности наследования 

1 ... 100 101 102 [ 103 ] 104 105 106 ... 265


Виртуальный конструктор-копировщик

Конструкторы не могут быть виртуальными, из чего можно сделать вывод, что не может быть также виртуального конструктора-копировщика. Но иногда требуется, чтобы профамма могла передать указатель на обьект базового класса и правильно скопировать его в обьект производного класса. Чтобы добиться этого, необходимо в базовом классе создать виртуальный метод С1опе(). Метод Clone() должен создавать и возвращать копию обьекта текущего класса.

Поскольку в производных классах метод С1опе() замещается, при вызове его создаются копии обьектов, соответствующие выбранному классу. Программа, использующая этот метод, показана в листинге 11.11.

Листинг 11.11. Виртуадьиый конструктор-коинровщнк

Листинг 11.11. Виртуальный конструктор-копировщик

ftinclude <iostream.h>

class Mammal {

public:

Mammal():itsAge(1) { cout Mammal constructor...\ n : } virtual MaiimialO { cout Mammal destructor. .. \ n ; } Mammal (const Mammal & rhs);

virtual void Speak() const { cout Mammal speak!\ n ; }

virtual Mammal* Clone() { return new Mammal(*this); }

int GetAgeOconst { return itsAge; } protected:

int itsAge; } ;

Mammal:: Mammal (const Mammal & rhs): itsAge( rhs. GetAgeO) {

cout << Mammal Copy Constructor...\ n ;

class Dog : public Mammal {

public:

DogO { cout << Dog constructor. .. \ n ; } virtual ~Dog() { cout Dog destructor...\ n ; } Dog (const Dog & rhs);

void SpeakOconst { cout << Woof!\ n ; } virtual Mammal* Clone() { return new Dog(*this); } } ;

Dog::Dog(const Dog & rhs):

Mammal(rhs)

cout Dog copy constructor...\ n ;



37; } 38;

39; class Cat : public Mammal 40: {

41: public:

42: CatO { cout Cat constructor, \ n ; } 43; CatO { cout Cat destructor.. ,\ n ; } 44; Cat (const Cat &);

45: void SpeakOconst { cout Meow!\ n ; }

46; virtual Mammal* CloneO { return new Cat( this); }

47: } ;

49; Cat: :Cat(const Cat & rhs): 50; Mammal(rhs) 51: {

52: cout Cat copy constructor..,\ n ;

53: }

55: enum ANIMALS { MAMMAL, DOG, CAT} ; 56: const int NumAnimalTypes = 3; 57; int mainO 58; {

59; Mammal *theArray[NumAnimalTypes]; 60: Mammal* ptr; 61; int choice, 1;

62: for ( i = 0; KNumAnimalTypes; i++) 63: {

64: cout (1)dog (2)cat (3)Mammal: ; 65: cin >> choice; 66: switch (choice) 67: {

68: case DOG: ptr = new Dog;

69: break;

70: case CAT: ptr = new Cat;

71: break:

72: default: ptr = new Mammal;

73: break;

74: }

75: theArray[i] = ptr; 76: }

77: Mammal *OtherArray[NumAnimalTypes]; 78: for (1=0; KNumAnimalTypes: i++) 79: {

80: theArray[i]->Speak();

81; OtherArray[i] = theArray[i]->Clone();

82; }

83: for (i=0; KNumAnimalTypes; 1++) 84: OtherArray[i]->Speak(); 85; return 0; 86: }



2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19

(1)dog (2)cat (3)Mammal: 1 Mammal constructor... Dog constructor... (1)dog (2)cat (3)Mammal: 2 Mammal constructor... Cat constructor... (1)dog (2)cat (З)МаттаГ. 3 Mammal constructor... Woof!

Mammal Copy Constructor... Dog copy constructor... Meow!

Mammal Copy Constructor... Cat copy constructor.,. Mammal speak!

Mammal Copy Constructor...

Woof I

Meow!

Mammal speak!

Листинг 11.11 похож на два предыдущих листинга, однако в данной про- грамме в классе Mammal добавлен один новый виртуальный метод -

С1опе(). Этот метод возвращает указатель на новый объект класса Mammal, используя конструктор-копировщик, параметр которого представлен указателем this.

Метод CloneO замещается в обоих производных классах - Dog и Cat - соответствующими версиями, после чего копии данных передаются на конструкторы-копировщики производных классов. Поскольку С1опе() является виртуальной функцией, то в результате будут созданы виртуальные конструкторы-копировщики, как показано в строке 81.

Пользователю предлагается выбрать объект класса Оод, Cat или Mammal. Объект выбранного типа создается в строках 62-74. В строке 75 указатель на новый объект добавляется в массив данных.

Затем осуществляется цикл, в котором для каждого объекта массива вызываются методы SpeakO и С1опе() (см. строки 80 и 81). В результате выполнения функции возвращается указатель на копию обьекта, которая сохраняется в строке 81 во втором массиве.

В строке 1 вывода на экран показан выбор пользователем опции 1 - создание объекта класса Dog, В создание этого объекта вовлекаются конструкторы базового и производного классов. Эта операция повторяется для объектов классов Cat и Mammal в строках вывода 4-8,

В строке 9 вывода показано выполнение метода Speak() для объекта класса Dog. Поскольку функция SpeakO также объявлена как виртуальная, то при обращении к ней вызывается та ее версия, которая соответствует типу объекта. Затем следует обращение еще к одной виртуальной функции CloneO, виртуальность которой проявляется в том, что при вызове из обьекта класса Dog запускаются конструктор класса Mammal и конструктор-копировщик класса Dog.

То же самое повторяется для обьекта класса Cat (строки вывода с 12-14) и объекта класса Mammal (строки вывода 15 и 16). В результате создается массив объектов, для каждого из которых вызывается своя версия функции Speak().



1 ... 100 101 102 [ 103 ] 104 105 106 ... 265

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика