Обработка виртуального деструктора выполняется правильно
pe->cuddle();
pe->highlight(); // правильно: Endangered::highlight()
delete pe; // правильно: Panda::~Panda()
Обработка виртуального деструктора выполняется правильно независимо от типа указателя, через который мы уничтожаем объект. Например, во всех четырех инструкциях порядок вызова деструкторов один и тот же – обратный порядку вызова конструкторов:
// ZooAnimal *pz = new Panda;
delete pz;
// Bear *pb = new Panda;
delete pb;
// Panda *pp = new Panda;
delete pp;
// Endangered *pe = new Panda;
delete pe;
Деструктор класса Panda вызывается с помощью механизма виртуализации. После его выполнения по очереди статически вызываются деструкторы Endangered и Bear, а в самом конце – ZooAnimal.
Почленная инициализация и присваивание объекту производного класса, наследующего нескольким базовым, ведут себя точно так же, как и при одиночном наследовании (см. раздел 17.6). Например, для нашего объявления класса Panda
class Panda : public Bear, public Endangered
{ ... };
в результате почленной инициализации объекта ling_ling
Panda yin_yang;
Panda ling_ling = yin_yang;
вызывается копирующий конструктор класса Bear (но, так как Bear производный от ZooAnimal, сначала выполняется копирующий конструктор класса ZooAnimal), затем – класса Endangered и только потом – класса Panda. Почленное присваивание ведет себя аналогично.
Упражнение 18.1
Какие из следующих объявлений ошибочны? Почему?
(a) class CADVehicle : public CAD, Vehicle { ... };
(b) class DoublyLinkedList:
public List, public List { ... };
(c) class iostream:
private istream, private ostream { ... };
Упражнение 18.2
Дана иерархия, в каждом классе которой определен конструктор по умолчанию:
class A { ... };
class B : public A { ... };
class C : public B { ... };
class X { ... };
class Y { ... };
class Z : public X, public Y { ... };
class MI : public C, public Z { ... };
Каков порядок вызова конструкторов в таком определении:
Содержание Назад Вперед