質問
C++ 標準は、派生クラスのデストラクタが実行された後、基本クラスのデストラクタが実行される前のオブジェクトの状態について何を保証しますか? (これは、派生クラスのサブオブジェクトのデストラクタが呼び出されている時間です。)
例
#include <string>
struct Base;
struct Member {
Member(Base *b);
~Member();
Base *b_;
};
struct Base {
virtual void f() {}
virtual ~Base() {}
};
struct Derived : Base {
Derived() : m(this) {}
virtual ~Derived() {}
virtual void f() {}
std::string s;
Member m;
};
Member::Member(Base *b) : b_(b) {}
Member::~Member() {
// At this point, ~Derived has finished -- can we use b_ as a
// Derived* object (i.e. call Derived::f or access Derived::s)?
b_->f();
}
int main() {
Base *bd = new Derived;
delete bd;
}
この例では、Member
オブジェクトはそれを所有するオブジェクトへのポインターを持っており、デストラクタが既に終了しているにもかかわらず、そのオブジェクトが破壊されるとDerived
、そのオブジェクトにアクセスしようとします。Derived
Derived
一部のサブオブジェクトが実行後、実行前に*bd
仮想関数を呼び出した場合、 の仮想関数のどのバージョンが呼び出されるでしょうか? その状態にあるときにアクセスすることは合法ですか?~Derived()
~Base()
*bd