удалить указатель типа A, указывающий на указатель типа B - PullRequest
1 голос
/ 14 июня 2011

Предположим, у меня есть указатель типа ABC * и другой указатель типа XYZ *, и оба являются производными от общего родительского класса.

Если я назначу XYZ * для ABC * путем явного приведения его, то что произойдетесли я позвоню

удалить abc;// abc типа XYZ *

получу ли я какое-либо исключение или оно будет работать нормально?

Я пробовал приведенный выше код, и он не вылетает.Так может кто-нибудь сказать мне, в каких случаях удаляется исключение выброса / ошибка / сбой и т. Д.

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

Редактировать: вот мой тестовый код, который работает без сбоев

class ABC
{
public:
    int a;
    int b;
    int c;
};

class XYZ
{
public:
    double a;
    double b;
    double c;
};

int main()
{
    ABC* abc = new ABC();
    XYZ* xyz = (XYZ*)abc;

    delete xyz;

    return 0;
}

PS: Я на платформе Windows, если это помогает.

EDIT2: Хорошо, после чтения я изменю свой вопрос на: когда удаление указателя вызовет сбой (не считая неопределенного поведения)?

EDIT3: Что произойдет при вызове удаления?Чей деструктор будет называться?

Ответы [ 4 ]

5 голосов
/ 14 июня 2011

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

См. ИСО / МЭК 14882: 2003 5.3.5 [expr.delete] /2.

5 голосов
/ 14 июня 2011

Если XYZ не является производным от ABC, вам не следует приводить объект первого к последнему - независимо от того, работает ваше удаление или нет, несущественно.

2 голосов
/ 14 июня 2011

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

0 голосов
/ 14 июня 2011

Если я назначу XYZ * для ABC *, явно приведя его

Если XYZ не является подклассом ABC, то такое явное приведение, будь то reinterpret_cast или приведение в стиле C, является неопределенным поведением. Иногда вам повезет, и программа будет работать правильно, даже если у нее неопределенное поведение. Не считайте своих счастливых звезд и никогда не вызывайте преднамеренного поведения.

...