2012-05-27 4 views
0
class A 
{ 
public: 
    int i; 
    ~A() 
    { 
     std::cout << "~A" << std::endl; 
    } 
}; 

class B: public A 
{ 
public: 
    int k; 
    ~B() 
    { 
     std::cout << "~B" << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    A* p = new B(); 
    delete p; 
    return 0; 
} 

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

Но это неопределенное поведение или нет?

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

ответ

7

Да, это. Удаление объекта производного class с помощью указателя на базовый класс без деструктора virtual - это учебник UB.

5.3.5/3:

В первом варианте (удалить объект), если статический тип операнда отличается от своего динамического типа, статического типа, должен быть базой класс динамического типа операнда и статический тип должны иметь виртуальный деструктор или поведение не определено. Во второй альтернативы (удалить массив), если динамический тип объекта, чтобы быть удален отличается от своего статического типа, поведение undefined.73)

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

+0

Вы когда-нибудь встречали такой код (производный класс не указывал на динамические данные) вызывали утечки? –

+0

@new_perl да, я сделал, но деструктор производного класса также освободил некоторую память. –

+0

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

4

Да, так как статические (здесь это A) отличается от динамического типа (B в вашем примере), и нет virtual деструктора, что это UB.

5.3.5/2 (5.3.5/3 в С ++ 11):

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

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