Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 11.11. Виртуальный конструктор-копировщик
1: //Листинг 11.11. Виртуальный конструктор-копировщик 2: 3: #include < iostream.h> 4: 5: class Mammal 6: { 7: public: 8: Mammal(): itsAge(1) { cout < < " Mammal constructor...\n"; } 9: virtual ^Mammal() { cout < < " Mammal destructor...\n"; } 10: Mammal (const Mammal & rhs); 11: virtual void Speak() const { cout < < " Mammal speak! \n"; } 12: virtual Mammal* Clone() { return new Mammal(*this); } 13: int GetAge()const { return itsAge; } 14: protected: 15: int itsAge; 16: }; 17: 18: Mammal:: Mammal (const Mammal & rhs): itsAge(rhs.GetAge()) 19: { 20: cout < < " Mammal Copy Constructor...\n"; 21: } 22: 23: class Dog: public Mammal 24: { 25: public: 26: Dog() { cout < < " Dog constructor...\n"; } 27: virtual ~Dog() { cout < < " Dog destructor...\n"; } 28: Dog (const Dog & rhs); 29: void Speak()const { cout < < " Woof! \n"; } 30: virtual Mammal* Clone() { return new Dog(*this); } 31: }; 32: 33: Dog:: Dog(const Dog & rhs): 34: Mammal(rhs) 35: { 36: cout < < " Dog copy constructor...\n"; 37: } 38: 39: class Cat: public Mammal 40: { 41: public: 42: Cat() { cout < < " Cat constructor,,, \n"; } 43: ~Cat() { cout < < " Cat destructor...\n"; } 44: Cat (const Cat &); 45: void Speak()const { cout < < " Meow! \n"; } 46: virtual Mammal* Clone() { return new Cat(*this); } 47: }; 48: 49: Cat:: Cat(const Cat & rhs): 50: Mammal(rhs) 51: { 52: cout < < " Cat copy constructor.., \n"; 53: } 54: 55: enum ANIMALS { MAMMAL, D0G, CAT }; 56: const int NumAnimalTypes = 3; 57: int main() 58: { 59: Mammal *theArray[NumAnimalTypes]; 60: Mammal* ptr; 61: int choice, i; 62: for (i = 0; i< NumAnimalTypes; 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 (i=0; i< NumAnimalTypes; i++) 79: { 80: theArray[i]-> Speak(); 81: OtherArray[i] = theArray[i]-> Clone(); 82: } 83: for (i=0; i< NumAnimalTypes; i++) 84: OtherArray[i]-> Speak(); 85: return 0; 86: }
Результат: 1: (1)dog (2)cat (3)Mammal: 1 2: Mammal constructor... 3: Dog constructor... 4: (1)dog (2)cat (3)Mammal: 2 5: Mammal constructor... 6: Cat constructor... 7: (1)dog (2)cat (3)Mammal: 3 8: Mammal constructor... 9: Woof! 10: Mammal Copy Constructor... 11: Dog copy constructor... 12: Meow! 13: Mammal Copy Constructor... 14: Cat copy constructor... 15: Mammal speak! 16: Mammal Copy Constructor... 17: Woof! 18: Meow! 19: Mammal speak!
Анализ: Листинг 11.11 похож на два предыдущих листинга, однако в данной программе в классе Mammal добавлен один новый виртуальный метод — Clone(). Этот метод возвращает указатель на новый объект класса Mammal, используя конструктор-копировщик, параметр которого представлен указателем < < this. Метод Clone() замещается в обоих производных классах — Dog и Cat — соответствующими версиями, после чего копии данных передаются на конструкторы- копировщики производных классов. Поскольку Clone() является виртуальной функцией, то в результате будут созданы виртуальные конструкторы-копировщики, как показано в строке 81. Пользователю предлагается выбрать объект класса 0og, Cat или Mammal. Объект выбранного типа создается в строках 62-74. В строке 75 указатель на новый объект добавляется в массив данных. Затем осуществляется цикл, в котором для каждого объекта массива вызываются методы Speak() и Clone() (см. строки 80 и 81). В результате выполнения функции возвращается указатель на копию объекта, которая сохраняется в строке 81 во втором массиве. В строке 1 вывода на экран показан выбор пользователем опции 1 — создание объекта класса Dog. В создание этого объекта вовлекаются конструкторы базового и производного классов. Эта операция повторяется для объектов классов Cat и Mammal в строках вывода 4-8. В строке 9 вывода показано выполнение метода Speak() для объекта класса Dog. Поскольку функция Speak() также объявлена как виртуальная, то при обращении к ней вызывается та ее версия, которая соответствует типу объекта. Затем следует обращение еще к одной виртуальной функции Clone(), виртуальность которой проявляется в том, что при вызове из объекта класса Dog запускаются конструктор класса Mammal и конструктор-копировщик класса Dog. То же самое повторяется для объекта класса Cat (строки вывода с 12—14) и объекта класса Mammal (строки вывода 15 и 16). В результате создается массив объектов, для каждого из которых вызывается своя версия функции Speak().
|