|
Программирование >> Дополнительные возможности наследования
Виртуальный конструктор-копировщик Конструкторы не могут быть виртуальными, из чего можно сделать вывод, что не может быть также виртуального конструктора-копировщика. Но иногда требуется, чтобы профамма могла передать указатель на обьект базового класса и правильно скопировать его в обьект производного класса. Чтобы добиться этого, необходимо в базовом классе создать виртуальный метод С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().
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |