为什么我的虚拟破坏者多次执行这些执行
Why does my virtual destructor executes these many times?
我一直在继承练习,我发现从基类指针指向继承类的deStuructor,结果为一个奇怪的输出,我发现我的destructor执行更多时间比应该。恢复我的代码(编辑:要求更多代码(:
#include <iostream>
using namespace std;
class B{
public:
virtual void f(){cout << "f() - B" << endl;}
virtual void g(){cout << "g() - B" << endl;}
virtual void h() = 0;
virtual ~B(){cout << "~B() destructor" << endl;}
protected:
int b;
};
class D1: virtual public B{
public:
void f(){cout << "f() - D1" << endl;}
virtual void g(){cout << "g() - D1" << endl;}
virtual ~D1(){cout << "~D1() destructor" << endl;}
protected:
int d1;
};
class D2: virtual public B{
public:
void f(int i){cout << "f(" << i << ") - D2" << endl;}
virtual void h(){cout << "h() - D2" << endl;}
virtual ~D2(){cout << "~D2() destructor" << endl;}
protected:
int d2;
};
class D3: public D1{
public:
void g(){cout << "g() - D3" << endl;}
void h(){cout << "h() - D3" << endl;}
private:
int d3;
};
class D4: public D1, public D2{
public:
using D1::f; using D2::f;
virtual ~D4(){cout << "~D4() destructor" << endl;}
private:
int d4;
};
void f(B& b){
cout << "f() out " << endl;
b.f();
b.g();
b.h();
};
int main()
{
B *pB;
D2 d2;
D3 d3;
D4 d4;
f(d2);
f(d3);
f(d4);
d4.D1::f();
d4.f(5);
d4.f(3.7);
d4.g();
d4.h();
pB = new D4;
pB -> f();
dynamic_cast<D4*>(pB)->f(3);
pB -> g();
pB -> h();
delete pB;
}
最终输出是:
//Other tests
.
.
.
f(3) - D2
~D4() destructor
~D2() destructor
~D1() destructor
~B() destructor
~D4() destructor
~D2() destructor
~D1() destructor
~B() destructor
~D1() destructor
~B() destructor
~D2() destructor
~B() destructor
创建PB指针;指向新的D4对象;向D4 F((方法和删除呼叫的明确调用。我期望只有四个destructor
呼叫;每个继承的类( d4,d2,d1 (,最后一个用于基类( b (。
这些结果应该正常吗?我的代码有问题吗?
您提供的代码分解以下输出:
f(3) - D2
~D4() destructor
~D2() destructor
~D1() destructor
~B() destructor
实时演示
您可以期待4个Destructor呼叫。~D4()->~D2()->~D1()->~B()
但是从输出来判断,您实际上删除了两个D4
对象,一个D1
对象和另一个D2
对象。
更新:
时称为击曲率- 您在对象上调用删除。
- 它不在范围内。
现在说明我的观点,我将介绍一个自定义范围:
int main()
{
B *pB;
{ // custom scope
D2 d2;
D3 d3;
D4 d4;
f(d2);
f(d3);
f(d4);
d4.D1::f();
d4.f(5);
d4.f(3.7);
d4.g();
d4.h();
pB = new D4;
pB->f();
dynamic_cast<D4*>(pB)->f(3);
pB->g();
pB->h();
}
delete pB;
}
调用此功能将打印以下输出:
//function calls
~D4() destructor <-- inside custom scope
~D2() destructor <-- inside custom scope
~D1() destructor <-- inside custom scope
~B() destructor <-- inside custom scope
~D1() destructor <-- inside custom scope
~B() destructor <-- inside custom scope
~D2() destructor <-- inside custom scope
~B() destructor <-- inside custom scope
~D4() destructor <-- outside custom scope
~D2() destructor <-- outside custom scope
~D1() destructor <-- outside custom scope
~B() destructor <-- outside custom scope
您的 D2
, D3
和 D4
对象分配在堆栈上,而分配在堆上的 D4
对象。您正在看到D1
,D2
和D4
驱动器的输出(您没有在D3
Destructor中输出任何内容(。
您认为delete
是灾难仪被调用的唯一方法吗?事实并非如此,但这似乎就是您在想的。您将为您创建的所有4个对象获取破坏者的输出消息。堆栈上的对象在main()
的末端出现范围时会自动破坏(以相反的创建顺序(。当您在其上明确调用delete
时,堆上的对象会破坏:
// when you delete pB...
~D4() destructor
~D2() destructor
~D1() destructor
~B() destructor
// when d4 goes out of scope...
~D4() destructor
~D2() destructor
~D1() destructor
~B() destructor
// when d3 goes out of scope...
~D1() destructor
~B() destructor
// when d2 goes out of scope...
~D2() destructor
~B() destructor
请参阅此实时演示,它具有与您显示的相同的驱动器输出。
如果您将输出添加到D3
的destructor:
class D3: public D1{
public:
void g(){cout << "g() - D3" << endl;}
void h(){cout << "h() - D3" << endl;}
virtual ~D3(){cout << "~D3() destructor" << endl;} // <-- add this!
private:
int d3;
};
// when d3 goes out of scope...
~D3() destructor <-- this message now appears
~D1() destructor
~B() destructor
相关文章:
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 无法在我的堆排序代码中找到错误.无法正确执行.C++
- 为什么我的最后一个 ELSE 条件无法正确执行
- 当我的 if 条件计算结果为 false 时,我的 else 块将不会执行
- 为什么我的信号处理程序只执行一次?
- 如何在不进入 Visual Studio 2015 中的外部库的情况下单步执行我的代码 (F11)
- 为什么程序运行时我的第二个循环不执行?
- 当我告诉它通过控制台执行此操作时,我的c ++循环不会停止
- 计算有多少人执行我的C++应用程序
- 为什么当我正确执行语法时,我的代码输出为 0
- 当循环正在执行我不明白的代码时
- 为什么重新执行我的多线程代码后输出不一样
- 执行我的代码的.exe结果时错误,但在调试器中执行该代码时没有错误
- 如何控制哪个numa节点执行我的程序
- 如何在睡眠期间按顺序执行我的动作?(C++,威纳皮)
- 围绕glutMainLoop执行我的其余程序
- 我的C++程序没有执行我的 cout 代码
- 在visualstudioc++2010中执行我的c++程序后收到发送错误报告
- 我怎么能随心所欲地执行我的职能呢
- 复制到程序文件(x86)时无法执行我的DLL