0
class Base{}; 
class D1:virtual public Base{}; 
class D2:virtual public Base{}; 
class DD:public D1,public D2{}; 

int main(){ 
    Base *pBase=new DD; 
    delete pBase; 
} 

Это приводит к сбою, но я могу изменить, как показано ниже:Destructor в виртуальном наследовании

class Base{ 
public: 
    virtual ~Base(){}; 
}; 

class D1:virtual public Base{ 
public: 
    virtual ~D1(){} 
}; 

class D2:virtual public Base{ 
public: 
    virtual ~D2(){} 
}; 

class DD:public D1,public D2{ 
}; 

Затем она проходит, но деструктор по умолчанию должен быть виртуальный манекен функции, не так ли?

+1

Пожалуйста, не отправляйте код с Microsoft '_tmain', если только это не код Visual C++. Это усложняет для других возможность попробовать ваш код и учит новичкам непривычные привычки. Исправлено это для вас. Просто используйте стандартный 'int main()'. –

+0

Что делает 'virtual' в инструкции:' class D: virtual public Base'? Я никогда не видел эту конструкцию (это может быть мое невежество ...). – Chiel

+1

@Chiel https://en.wikipedia.org/wiki/Virtual_inheritance, он используется, когда вы наследуете несколько классов, которые используют одну и ту же базу. – Holt

ответ

2

Это не имеет ничего общего с виртуальным наследованием.

Удаление с помощью указателя типа T, отличного от первоначально выделенного типа D, является неопределенным поведением, если только тип T не является базовым классом D и имеет виртуальный деструктор.

С ++ 14 (как в проекте N3936) §5.3.5/3

& hellip; если статический тип подлежащего удалению объекта отличается от его динамического типа , статический тип должен быть базовым классом динамического типа объекта, подлежащего удалению, и статический тип должен иметь виртуальный деструктор или поведение не определено.

Виртуальный деструктор используется для идентификации типа D, в частности его размера и его деструктора, и, возможно, его пользовательской функции освобождения (ваш код не имеет этого).


Re

деструктор по умолчанию должен быть виртуальный манекен функции, не так ли?

Нет, это не так.

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

Вы получаете виртуальный деструктор по умолчанию, только если базовый класс имеет виртуальный деструктор.

2

От C++ 11 Спецификация (ISO/IEC 14882: 2011 (Е)), раздел 12.4 деструкторы [class.dtor]:

Подраздел 4:

Если класс не имеет объявленного пользователем деструктора, деструктор неявно объявляется дефолтом (8.4). Неявно объявленный деструктор является встроенным публичным членом своего класса.

Подраздел 6:

деструктор, который устанавливается по умолчанию, и не определен как удаленный неявно определяется, когда оно ODR-используется (3.2), чтобы уничтожить объект своего типа класса (3.7) или когда он явно дефолт после первого объявления.

И, наконец, подраздел 9:

Деструктор может быть объявлен виртуальным (10.3) или чисто виртуальное (10.4); если в программе создаются какие-либо объекты этого класса или любого производного класса, деструктор должен быть определен. Если класс имеет базовый класс с виртуальным деструктором, его деструктор (независимо от того, объявлен ли пользователь или неявно) является виртуальным.

Акцент в последней цитате.

Компилятор будет генерировать виртуальный деструктор только, если базовый класс имеет виртуальный деструктор. Если базовый класс не имеет виртуального деструктора, например, Base в вашем первом примере, тогда у дочерних классов не будет виртуальных деструкторов. И если класс не имеет базового класса, деструктор, созданный компилятором, не будет виртуальным.

+0

спасибо ~~~, я получаю –

 Смежные вопросы

  • Нет связанных вопросов^_^