order of destruction using virtual

Can some one please help what the order of destruction is when I am using virtual functions. Does it start with the base class and then derived class?

10
задан Melebius 11 September 2017 в 08:21
поделиться

8 ответов

Поскольку я не вижу, как виртуальная функция изменяет порядок уничтожения каких-либо объектов, я предполагаю, что вы имеете в виду порядок уничтожения для базовых классов и членов данных в сценарии виртуального наследования .

Подобъекты построены

  1. базовые классы построены от наиболее базовых к наиболее производным ;
  2. несколько базовых классов построены в порядок их объявления в качестве базовых классов ;
  3. виртуальные базовые классы конструируются раньше всех остальных , между собой соблюдая два вышеуказанных правила;
  4. элементы данных конструируются перед выполнением тела конструктора включающего объекта в порядке их объявления.

Разрушение просто противоположно конструкции , поэтому вам нужно только запомнить сказанное выше.

Однако приведенные выше четыре правила расположены в таком порядке, потому что это имеет смысл, и если вы поймете, почему этот порядок имеет смысл, вам даже не придется запоминать эти четыре правила, но вы сможете вывести их из своего понимания (как я только что сделал). Итак, давайте рассмотрим этот порядок:

  • Вы можете захотеть использовать любую услугу, предоставляемую базовым классом из конструктора производного класса. Конечно, вы не можете использовать объект (базового) класса до его фактического создания. Следовательно, когда создается производный класс, базовый класс должен быть уже построен.(Между прочим, это также объясняет, почему диспетчеризация виртуальных функций не работает полностью из конструкторов: когда подобъект построен, уже созданы только подобъекты базовых классов; подобъекты производных классов еще не созданы. Следовательно, вызов виртуальной функции не должен отправляться в производный класс. Как всегда, деструкторы одинаковы, только наоборот.)
  • Поскольку несколько базовых классов были равными братьями и сестрами, некоторый порядок нужно было выбирать произвольно. В конечном итоге порядок объявления является наиболее простым в использовании. Члены данных, которые также являются равными братьями и сестрами, подчиняются одному и тому же (более или менее произвольному) правилу порядка объявления.
  • Виртуальные базовые классы - странные звери. Поскольку всегда будет только один подобъект виртуального базового класса, существует специальное правило, которое гласит, что его всегда нужно создавать первым, прямо из конструктора самого производного класса. (Вот почему виртуальные базовые классы лучше всего работают как абстрактные базовые классы без данных и только с конструкторами по умолчанию.)
13
ответ дан 3 December 2019 в 19:31
поделиться

Предполагая, что вы правильно объявили свой деструктор как виртуальный.

Затем разрушение происходит в прямо противоположном порядке построения.

В целом это будет:

A) Запуск в наиболее производном классе.
Б) Повторите следующее рекурсивно.

1) Выполнить код деструктора.
2) Выполните деструктор каждого члена (в обратном порядке создания)
3) Выполнить деструктор родительского класса. (если более одного в обратном порядке создания)

Если вы используете виртуальное наследование, тогда все будет немного иначе, поскольку порядок построения базового класса не такой, как обычно. НО Порядок уничтожения ВСЕГДА обратный порядку построения.

5
ответ дан 3 December 2019 в 19:31
поделиться

Порядок уничтожения - это порядок строительства в обратном порядке. Недавно я сделал небольшой инструмент для отображения порядка построения любой иерархии. Посмотрите здесь:

На диаграммах узлы с меньшими номерами конструируются первыми и уничтожаются последними .

1
ответ дан 3 December 2019 в 19:31
поделиться

Это противоположно конструкторам. Так поступили в первую очередь.

0
ответ дан 3 December 2019 в 19:31
поделиться

Виртуальные функции не влияют на порядок уничтожения, а виртуальные базовые классы - наоборот.

Без виртуальных базовых классов производные классы всегда уничтожаются раньше, чем их базовые классы; это обратный порядок их построения.

Для наиболее производного класса сначала создаются виртуальные базовые классы, перед другими базовыми классами и перед самим производным классом. Уничтожение происходит в обратном порядке. Это означает, что виртуальная база может быть уничтожена после класса, который является производным от нее виртуально, если этот класс не является самым производным классом, который уничтожается. Этого никогда не может случиться с прямыми базовыми классами.

0
ответ дан 3 December 2019 в 19:31
поделиться

Порядок разрушения снизу вверх. (от производного к основанию)

Краткий ответ: полная противоположность порядок конструктора.

Длинный ответ: предположим, что "наиболее производным "классом является D, что означает реальный объект, который изначально был created был класса D, и что D наследует умножение (и не виртуально) из B1 и B2. Подобъект соответствующий наиболее производному классу D сначала запускается, затем следуют dtors для его невиртуальные базовые классы в обратное объявление-заказ. Таким образом порядок деструктора будет D, B2, B1. Это правило применяется рекурсивно; за Например, если B1 наследуется от B1a и B1b, а B2 наследуется от B2a и B2b, окончательный заказ - D, B2, B2b, B2a, B1, B1b, B1a.

См. раздел часто задаваемых вопросов по c ++.

0
ответ дан 3 December 2019 в 19:31
поделиться

Сначала производное, затем основание. Никакой разницы по сравнению с невиртуальными случаями.

Дополнительное примечание. Когда у вас есть наследование и виртуальные методы, вы должны объявить деструкторы как виртуальные, иначе вы можете иметь неопределенное поведение при удалении.

Пример, предположим, что Derived является производным от Base, и вы выделяете Derived следующей строкой:

Base *o = new Derived();
delete(o);

Если этот случай встречается в вашем коде, а Base не имеет виртуального деструктора, результирующее поведение не определено. Обычно вызывается только деструктор Base. Деструктор Derived не будет вызываться, потому что вы вызываете удаление для указателя Base. Однако вместо этого может произойти сбой программы. Как только вы попадаете в область неопределенного поведения, все ставки прекращаются, и ваш рабочий код обречен. Чтобы предотвратить хаос, деструктор Base должен быть виртуальным.

0
ответ дан 3 December 2019 в 19:31
поделиться

Раздел 12.6.2 / 5:

Инициализация должна выполняться в следующем порядке:

  • Сначала и только для конструктора самого производного класса как как описано ниже, виртуальные базовые классы должны быть инициализированы в порядка их появления при обходе слева направо в глубину ориентированный ациклический граф базовых классов, где «слева направо» - порядок появления имен базовых классов в производном классе базовый-спецификатор-список.
  • Затем должны быть инициализированы прямые базовые классы. в порядке объявления, как они появляются в списке спецификаторов базы (независимо от порядка инициализаторов памяти).
  • Тогда нестатический элементы данных должны быть инициализированы в том порядке, в котором они были объявлены определение класса (опять же, независимо от порядка mem-инициализаторы). - Наконец, тело конструктора выполнено.

[Примечание: приказ об объявлении должен гарантировать, что база и подобъекты-члены уничтожаются в порядке, обратном инициализация. ]

1
ответ дан 3 December 2019 в 19:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: