简体   繁体   English

在 C++ 继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数

[英]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.

相关问题 使用基本 class 指针创建 object 时缺少派生 class 析构函数 - Missing Derived class Destructor when object is created with the base class pointer 派生类包含指向基类对象的指针时的析构函数 - Destructor when derived class contains a pointer to base class object 当派生类的析构函数是非虚拟的时,为什么基类析构函数在派生对象上调用? - Why is base-class destructor called on derived object when destructor of derived class is non-virtual? C ++继承:派生类指向基类的指针将调用派生类方法 - C++ Inheritance: Derived class pointer to a Base class invokes Derived class method C ++继承:定义指向派生类或基类的指针 - C++ inheritance: defining a pointer to either derived or base class 指向C ++中派生类的基类指针 - the base class pointer to the derived class in c++ 如何在c ++中将指向基类的指针赋给派生类的对象? - How to assign a pointer to base class to an object of a derived class in c++? C ++从派生类指针获取基类对象? - c++ get base class object from derived class pointer? 虚拟析构函数在基类和派生类中未调用 - Virtual Destructor Not called in Base as well as Derived Class 什么时候需要基类指针指向C ++中的派生类对象? - When do you need a base class pointer to a derived class object in C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM