18.5.3. Порядок вызова конструкторов и деструкторов

We use cookies. Read the Privacy and Cookie Policy

18.5.3. Порядок вызова конструкторов и деструкторов

Виртуальные базовые классы всегда конструируются перед невиртуальными, вне зависимости от их расположения в иерархии наследования. Например, в приведенной иерархии у класса TeddyBear (плюшевый мишка) есть два виртуальных базовых: непосредственный – ToyAnimal (игрушечное животное) и экземпляр ZooAnimal, от которого унаследован класс Bear:

class Character { ... }; // персонаж

class BookCharacter : public Character { ... };

// литературный персонаж

class ToyAnimal { ... }; // игрушка

class TeddyBear : public BookCharacter,

public Bear, public virtual ToyAnimal

{ ... };

Эта иерархия изображена на рис. 18.5, где виртуальное наследование показано пунктирной стрелкой, а невиртуальное – сплошной.

Рис. 18.5. Иерархия виртуального наследования класса TeddyBear

Непосредственные базовые классы просматриваются в порядке их объявления при поиске среди них виртуальных. В нашем примере сначала анализируется поддерево наследования BookCharacter, затем Bear и наконец ToyAnimal. Каждое поддерево обходится в глубину, т.е. поиск начинается с корневого класса и продвигается вниз. Так, для поддерева BookCharacter сначала просматривается Character, а затем BookCharacter. Для поддерева Bear – ZooAnimal, а потом Bear.

При описанном алгоритме поиска порядок вызова конструкторов виртуальных базовых классов для TeddyBear таков: ZooAnimal, потом ToyAnimal.

После того как вызваны конструкторы виртуальных базовых классов , настает черед конструкторов невиртуальных, которые вызываются в порядке объявления: BookCharacter, затем Bear. Перед выполнением конструктора BookCharacter вызывается конструктор его базового класса Character.

Если имеется объявление:

TeddyBear Paddington;

то последовательность вызова конструкторов базовых классов будет такой:

ZooAnimal(); // виртуальный базовый класс Bear

ToyAnimal(); // непосредственный виртуальный базовый класс

Character(); // невиртуальный базовый класс BookCharacter

BookCharacter(); // непосредственный невиртуальный базовый класс

Bear(); // непосредственный невиртуальный базовый класс

TeddyBear(); // ближайший производный класс

причем за инициализацию ZooAnimal и ToyAnimal отвечает TeddyBear – ближайший производный класс объекта Paddington.

Порядок вызова копирующих конструкторов при почленной инициализации (и копирующих операторов присваивания при почленном присваивании) такой же. Гарантируется, что деструкторы вызываются в последовательности, обратной вызову конструкторов.