[英]In C++ Inheritance, Derived class destructor not called when pointer object to base class is pointed to derived class
I am a newbie and I know this is a very basic concept and might be a duplicate too.我是新手,我知道这是一个非常基本的概念,也可能是重复的。 Is it not true that once a constructor is called its corresponding destructor has to be called?
一旦调用了构造函数,就必须调用其相应的析构函数,这不是真的吗? [code run on Dev C++]
[在 Dev C++ 上运行的代码]
class Base
{
public:
Base() { cout<<"Base Constructor\n";}
int b;
~Base() {cout << "Base Destructor\n"; }
};
class Derived:public Base
{
public:
Derived() { cout<<"Derived Constructor\n";}
int a;
~Derived() { cout<< "Derived Destructor\n"; }
};
int main () {
Base* b = new Derived;
//Derived *b = new Derived;
delete b;
getch();
return 0;
}
GIVES OUTPUT给出输出
Base Constructor
Derived Constructor
Base Destructor
Your code has undefined behavior.您的代码具有未定义的行为。 The base class's destructor must be
virtual
for the following to have defined behavior.基类的析构函数必须是
virtual
的,才能具有定义的行为。
Base* b = new Derived;
delete b;
From the C++ standard:从 C++ 标准:
5.3.5 Delete
5.3.5 删除
3 In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined.
3 在第一种选择(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数动态类型的基类,静态类型应具有虚拟析构函数或行为为不明确的。
So in your case, the static type is Base
, and the dynamic type is Derived
.所以在你的情况下,静态类型是
Base
,动态类型是Derived
。 So the Base
's destructor should be:所以
Base
的析构函数应该是:
virtual ~Base() {cout << "Base Destructor\n"; }
There is no need to call a destructor if it is trivial.如果它是微不足道的,则无需调用析构函数。
That does not help in your example though, because if a class has a sub-object with non-trivial destructor (member or base) or its own destructor is user-defined, it is not trivial.但是,这在您的示例中无济于事,因为如果一个类具有一个具有非平凡析构函数(成员或基类)的子对象,或者它自己的析构函数是用户定义的,则它不是微不足道的。
Also, you may only delete a class using a pointer to base, if that base-class has a virtual
destructor, on pain of undefined behavior (The compiler need not warn you).此外,您只能使用指向基类的指针删除类,如果该基类具有
virtual
析构函数,则可能会遇到未定义行为的痛苦(编译器不需要警告您)。
Pro-tip: If you need to make it virtual (for example due to above requirement), but do not want to prevent it from being trivial (some containers and algorithms have optimized implementations for trivial types), use:专业提示:如果您需要使其成为虚拟的(例如由于上述要求),但又不想防止它变得琐碎(某些容器和算法已针对琐碎类型进行了优化实现),请使用:
virtual ~MyClass = default; // Since C++11
So, never delete using a pointer to Base
if Base
does not have a virtual destructor or it is actually really a base.因此,如果
Base
没有虚拟析构函数或者它实际上是一个基类,则永远不要使用指向Base
的指针进行删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.