なぜ次のコードがクラッシュしないのか、それがどう処理されないのか説明してください。オブジェクトポインタでデストラクタを呼び出す
class Base
{
public:
Base() {cout << "Base constr" << endl;}
virtual void func() {cout << "Base func()" << endl;}
virtual ~Base() {cout << "Base destr" << endl;}
};
class Layer1 : public Base
{
public:
Layer1() {cout << "Layer1 constr" << endl;}
virtual void func() {cout << "Layer1 func()" << endl;}
virtual ~Layer1() {cout << "Layer1 destr" << endl;}
};
class Layer2 : public Layer1
{
public:
Layer2() {cout << "Layer2 constr" << endl;}
virtual void func() {cout << "Layer2 func()" << endl;}
~Layer2() {cout << "Layer2 destr" << endl;}
};
int main(int argc, char** argv)
{
Layer2 * l2ptr = (Layer2 *) new Base;
l2ptr->func();
delete l2ptr;
return 0;
}
出力:
Base constr
Base func()
Base destr
私はl2ptrが呼び出された時点で削除を意味します。最初の外観からは、Layer2
デストラクタを呼び出す必要がありますが、Layer2
オブジェクトは作成されていないようです。また、Layer2
デストラクタはvirtual
ではありません。私がそれを仮想化すると、出力は同じになります。どうして?
そして、次の質問:それは子クラスポインタによって親クラスオブジェクトにアクセスする際にどのような問題と考慮事項がありますか?
EDIT: 私はこのようなこの
class Layer2 : public Layer1
{
public:
Layer2() {cout << "Layer2 constr" << endl;}
virtual void func() {cout << "Layer2 func()" << endl;}
void func2() {cout << "Layer2 func2()" << endl;}
virtual ~Layer2() {cout << "Layer2 destr" << endl;}
};
そしてmain()
にLayer2
クラスを変更した場合:
int main(int argc, char** argv)
{
Layer2 * l2ptr = (Layer2 *) new Base;
l2ptr->func();
l2ptr->func2();
delete l2ptr;
return 0;
}
それはまだ動作し、出力は次のとおりです。
Base constr
Base func()
Layer2 func2()
Base destr
再び、 どうして?
コードに未定義の動作があります。それは何かが起こりうることを意味し、あなたは何かが起こっていることを観察しています。 –
あなたは '(Layer2 *)new Base'の少し後にUBを持っています... – Jarod42
http://blog.llvm.org/2016/04/undefined-behavior-is-magic.html – JVApen