Если предположить, что это не виртуальные/множественное наследование (что усложняет вещи совсем немного), то правила просты:
- Память объект выделяется
- Конструктор базовых классов выполняются, заканчивая наиболее полученного
- инициализация элемента выполнена
- объект становится настоящим экземпляром этого класса
код
- конструктора выполняется
Важно помнить, что до этапа 4 объект еще не является экземпляром его класса, поскольку он получает этот заголовок только после начала конструктора. Это означает, что если в конструкторе элемента есть исключение, деструктор объекта не выполняется, а только уже сконструированные части (например, члены или базовые классы) будут уничтожены. Это также означает, что если в конструкторе члена или базового класса вы вызываете любую виртуальную функцию-член объекта, то названная реализация будет базовой, а не производной. Еще одна важная вещь, которую следует помнить, состоит в том, что член, указанный в списке инициализации, будет создан в том порядке, в котором они объявлены в классе, а не в том порядке, в котором они отображаются в списке инициализации (к счастью, большинство достойных компиляторов выдадут предупреждение, если вы перечислите члены в другом порядке из декларации класса).
Следует также отметить, что даже если во время выполнения конструктора коды this
объекта уже получил свой окончательный класс (например, в отношении виртуальной отправки) деструктора класса не будет называться, если конструктор не завершит выполнение , Только когда конструктор завершает выполнение, экземпляр объекта является реальным гражданином первого класса среди экземпляров ... до этого момента это всего лишь «желаемый экземпляр» (несмотря на наличие правильного класса).
Уничтожение происходит в точном обратном порядке: сначала выполняется деструктор объекта, затем он теряет свой класс (т. Е. Из этой точки на объекте считается базовым объектом), тогда все члены уничтожаются в обратном порядке объявления и, наконец, процесс разрушения базового класса выполняется до самого абстрактного родителя. Что касается конструктора, если вы вызываете любую виртуальную функцию-член объекта (прямо или косвенно) в деструкторе базы или члена, исполняемая реализация будет родительской, потому что объект потерял название класса при завершении деструктора класса.
Ваш пример может быть более объяснительным, если ваше сообщение для деструктора отличается от вашего сообщения для конструктора. Кроме того, что такое 'std :: sort'? – Tom
Кроме того, при экспериментировании сравните конструкцию и разрушение 'B b',' B * b = new B(); delete b; 'и' A * a = new b(); delete a; '(Сравните, что происходит, когда вы используете ключевое слово' virtual' для вашего деструктора, то есть 'virtual ~ A() {cout <<" D-tor "<< endl;}') – Tom
@Tom, вы правильно. Удаление ошибок компилятора. – iammilind