2015-07-20 1 views
9

Является ли порядок разрушения хорошо определенным в случае множественного наследования?Порядок уничтожения в случае множественного наследования

struct A 
{ 
    ~A(){std::cout << "A\n";} 
}; 

struct B 
{ 
    ~B(){std::cout << "B\n";} 
}; 

struct AB : public B, public A 
{ 
    ~AB(){std::cout<<"AB\n";} 
}; 

int main() 
{ 
    AB ab; 
} 

Для данного кода мой компилятор печатает:

AB 
B 
A 

Buf я использую более сложные конструкции (в том числе CWinApp), я получаю разные результаты. Итак, порядок четко определен? И если да, то какое правило заказа?

+4

Да, разрушение в обратном порядке декларации. –

+3

Какой компилятор вы используете, это то, что печатается? Должен ли AB, A, B. – Barry

+0

Я использую Visual Studio 2013 – user1235183

ответ

14

Из [class.dtor]:

Основания и члены уничтожаются в порядке, обратном порядку завершения их конструктора (см 12.6.2).

Упорядочение конструктор, из [class.base.init]:

В не делегировании конструктор, инициализация происходит в следующем порядке:
- Во-первых, и только для конструктора самый производный класс (1.8), виртуальные базовые классы инициализируются [...]
- Затем прямые базовые классы инициализируются в порядке объявления, как они отображаются в списке базового-спецификатора (независимо от порядка mem-init ializers).

Для примера:

struct AB : public B, public A 

Порядок строительства B затем A затем AB. Таким образом, порядок уничтожения - AB, затем A, затем B.

6

C++ 11 Стандарт делает это ясно (S10.1), для множественного наследования

Порядок вывода не имеет существенного значения, кроме как указано в семантики инициализации с помощью конструктора (12.6.2), очистка (12.4), и расположение хранилища (9.2, 11.1).

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

+0

Это означает, что возможен любой порядок разрушения? – user1235183

+1

Таким образом, заказ не является существенным, за исключением очистки. Какой порядок очистки? – Barry

1

От friendly manual (сокращенные # 2 бит):

  1. деструктора класса называется.
  2. Деструкторы для нестатических элементов в обратном порядке декларации.
  3. Деструкторы для невиртуальных базовых классов вызывают в обратном порядке объявления.
  4. Деструкторы для виртуальных базовых классов вызывают в обратном порядке объявления.

Так что ваш компилятор генерирует код, который Уничтожает в порядке АВ, В, А.

[редактировать 20150725: повторяющиеся комментарии Барри в конце концов, привело меня заметить, что я typoed «Это не», как "Это тоже". Конечно, набрав его, я не мог его увидеть, пока не закончил . Мех. Таким образом, один изменил слово в следующем.]

Это не заказ от isocpp.org-х FAQ. Эта запись относится к одному и тому же вопросу о заказе конструктора, где текст «Обратите внимание, что порядок B1, а затем B2 (или B1a, затем B1b) определяется порядком, в котором базовые классы появляются в объявлении класса, а не в порядке что инициализатор появляется в списке инициализации производного класса ». появляется, указывая, что порядок объявления является соответствующим заказом.

+0

Вы говорите «обратный порядок объявления», но тогда вы говорите «AB, B, A». Что он? B был объявлен до A. – Barry

+0

@Barry: От источника: структура A объявлена ​​в строке 1 (и сразу определена), тогда структура B объявляется в строке 6, тогда структура AB объявляется в строке 11. Итак, ясно, что A объявляется до B. Кроме того, этот порядок фактически соответствует результату его кода. –

+0

Это порядок, в котором они объявлены как основы, а не порядок, в котором объявляются сами классы. В списке спецификаторов базы сначала находится B. – Barry