Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 11.9. Произвольное обращение к набору виртуальных функций
1: //Листинг 11.9. Произвольное обращение к набору виртуальных функций 2: 3: #include < iostream.h> 4: 5: class Mammal 6: { 7: public: 8: Mammal(): itsAge(1) { } 9: virtual ~Mammal() { } 10: virtual void Speak() const { cout < < " Mammal speak! \n"; } 11: protected: 12: int itsAge; 13: }; 14: 15: class Dog: public Mammal 16: { 17: public: 18: void Speak()const { cout < < " Woof! \n"; } 19: }; 20: 21: 22: class Cat: public Mammal 23: { 24: public: 25: void Speak()const { cout < < " Meow! \n"; } 26: }; 27: 28: 29: class Horse: public Mammal 30: { 31: public: 32: void Speak()const { cout < < " Whinny! \n"; } 33: }; 34: 35: class Pig: public Mammal 36: { 37: public: 38: void Speak()const < cout < < " Oink! \n"; } 39: }; 40: 41: int main() 42: { 43: Mammal* theArray[5]; 44: Mammal* ptr; 45: int choice, i; 46: for (i = 0; i< 5; i++) 47: { 48: cout < < " (1)dog (2)cat (3)horse (4)pig: "; 49: cin > > choice; 50: switch (choice) 51: { 52: case 1: ptr = new Dog; 53: break; 54: case 2; ptr = new Cat; 55: break; 56: case 3: ptr = new Horse; 57: break; 58: case 4: ptr = new Pig; 59: break; 60: default: ptr = new Mammal; 61: break; 62: } 63: theArray[i] = ptr; 64: } 65: for (i=0; i< 5; i++) 66: theArray[i]-> Speak(); 67: return 0; 68: }
Результат: (1)dog (2)cat (3)horse (4)pig: 1 (1)dog (2)cat (3)horse (4)pig: 2 (1)dog (2)cat (3)horse (4)pig: 3 (1)dog (2)cat (3)horse (4)pig; 4 (1)dog (2)cat (3)horse (4)pjg: 5 Woof! Meow! Whinny! 0ink! Mammal speak!
Анализ: Чтобы идея использования виртуальных функций была понятнее, в данной программе этот метод раскрыт наиболее явно и четко. Сначала определяется четыре класса — Dog, Cat, Horse и Pig, которые являются производными от базового класса Mammal. В строке 10 объявляется виртуальная функция Speak() класса Mammal. В строках 18, 25, 32 и 38 указанная функция замещается во всех соответствующих производных классах. Пользователю предоставляется возможность выбрать объект любого производного класса, и в строках 46—64 создается и добавляется в массив указатель класса Mammal на вновь созданный объект.
Вопросы и ответы Если функция-член была объявлена как виртуальная в базовом классе, следует ли повторно указывать виртуальность при объявлении этого метода в произ- водном классе? Нет. Если метод уже был объявлен как виртуальный, то он будет оставаться таким, несмотря на замещение его в производном классе. В то же время для повышения читабельности программы имеет смысл (но не требуется) и в производных классах продолжать указывать на виртуальность данного метода с помощью ключевого слова virtual.
Примечание: Во время компиляции неизвестно, объект какого класса захочет создать пользователь и какой именно вариант метода Speak() будет использоваться. Указатель ptr связывается со своим объектом только во время выполнения программы. Такое связывание указателя с объектом называется динамическим, в отличие от статического связывания, происходящего во время компиляции программы.
|