2015-10-19 1 views
0

Я считаю, что я нашел ошибку для существующего кода, но он действительно работает. Не могли бы вы помочь проверить правильность моего понимания?Родительский удержание указателя на дочерний элемент данных и использование функции члена данных в деструкторе

Речь идет о родительском классе, содержащем указатель объекта, который указывает на объект данных его дочернего класса. И в своем (родительском) деструкторе он использует указатель объекта для доступа к функции. Я верю, когда вызывается родительский деструктор, ребенок уже был разрушен, поэтому объект, указатель родительского указателя которого уже недействителен. Ниже приведен пример:

Мой вопрос для кода ниже состоит в том, что если родительский деструктор верен?

#include <iostream> 
#include <string> 
using namespace std; 

class object { 
public: 

    object(string na):name(na){} 

    string get_name(){ 
     return name; 
    } 

private: 
    string name; 
}; 

class parent { 

public: 

    ~parent(){ 
     cout<<"hello"<<endl; 
     cout<<mp->get_name(); **//!!!! (is this correct use mp here?)** 
    } 
protected: 
    object* mp; 

}; 


class child:public parent { 

public: 

    child():m("hello"){ 
     parent::mp=&m; 
    } 


private: 
    object m; 
}; 

int main() 
{ 

child a; 

return 0; 
} 
+1

Неуловимый «это на самом деле работает» является одним из примеров неопределенного поведения. – molbdnilo

ответ

2

Я верю, когда родительский деструктор, ребенок уже уничтожены

§ 12.4.8 собирается стать моим любимым стандартом цитаты.

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

Деструкторы для членов выполнены после кузова класса dtor, поэтому можно безопасно вызвать функцию члена.

, как говорится ...

В вашем случае, в то время как mp вполне допустимо, то значение это указывает на нет. Начиная с parent деструктор запускается после деструктора child, значение которого является владельцем, также уничтожается, оставив родителя с висящим указателем.

+0

Все, что вы написали, верно, я имею в виду, что это не вся картина. Да, деструкторы для членов выполняются после тела. Но после этого выполняется родительский деструктор. – Stas

+0

@stas спасибо и извините за путаницу.Я предпочел бы, чтобы вы использовали слово «неполное», чем «неправильное» :). Как и в, я думал, что вы видели фактическую проблему в моем ответе. –

+0

Да, формулировка не моя сила) – Stas

1

Неправильно.

Последовательность деструкторов вызовов:

  1. child деструктор
  2. object деструктор (как член child класса)
  3. parent деструктор

Посмотрите на это: родитель держит указатель на object, который является членом класса child.

child():m("hello"){ 
    parent::mp=&m; 
} 

Так, object уже разрушается при попытке получить к нему доступ через указатель в parent деструктора:

~parent(){ 
    cout<<"hello"<<endl; 
    cout<<mp->get_name(); //!!!! this is incorrect 
}