有继承的C++析构函数一定要用virtual

35 篇文章 0 订阅

先补下virtual是啥

虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。 

 

先贴个代码,再解释

复制代码
#include <iostream>

using namespace std;

class Base
{
public:
    Base(){cout<<"Base Construct"<<endl;};
    ~Base(){cout<<"Base destroy"<<endl;}
       
};

class A : public Base
{
public:
    A(){cout<<"A Construct"<<endl;}
    ~A(){cout<<"A destroy"<<endl;}
};
class Base1
{
public:
    Base1(){cout<<"Base1 Construct"<<endl;};
    virtual  ~Base1(){cout<<"Base1 destroy"<<endl;}
       
};

class A1 : public Base1
{
public:
    A1(){cout<<"A1 Construct"<<endl;}
    ~A1(){cout<<"A1 destroy"<<endl;}
};

int main()
{
    Base* p = new A;
    delete p;
    cout<<"======================"<<endl;
    Base1* p1 = new A1;
    delete p1;
    return 0;
}
/*
  Base Construct
  A Construct
  Base destroy
  ======================
  Base1 Construct
  A1 Construct
  A1 destroy
  Base1 destroy
*/
复制代码

在代码尾部的注释就是输出。

Base的析构函数没有virtual

Base1的析构函数有virtual

 

Base* p = new A

delete p

这个过程只调用了Base的析构函数,没有调用A的析构函数。

这样在实际应用中会有不确定的后果,可能会memory leak

应该在A的析构函数中我们可能会销毁一些其他的资源,而这里并未调用。

所以要给Base的析构函数以virtual属性。

假设我们有如下的多重继承和派生的类: ```c++ class A { public: A() { cout << "Constructing A" << endl; } virtual ~A() { cout << "Destructing A" << endl; } }; class B { public: B() { cout << "Constructing B" << endl; } virtual ~B() { cout << "Destructing B" << endl; } }; class C : public A, public B { public: C() { cout << "Constructing C" << endl; } ~C() { cout << "Destructing C" << endl; } }; ``` 在类 `C` 中,我们同时继承了类 `A` 和类 `B`,并且派生出了一个新的类 `C`。为了保证内存的正确释放,我们需要在 `C` 类的析构函数中调用 `A` 和 `B` 的析构函数。 ```c++ int main() { C obj; return 0; } ``` 当我们创建一个 `C` 类型的对象时,构造函数的输出应该是: ``` Constructing A Constructing B Constructing C ``` 当程序结束时,析构函数的输出应该是: ``` Destructing C Destructing B Destructing A ``` 因此,我们需要在 `C` 类的析构函数中调用 `A` 和 `B` 的析构函数: ```c++ class C : public A, public B { public: C() { cout << "Constructing C" << endl; } ~C() { cout << "Destructing C" << endl; // 调用 A 和 B 的析构函数 A::~A(); B::~B(); } }; ``` 注意,我们在调用 `A` 和 `B` 的析构函数时,使用了作用域限定符 `::`。这是因为我们需要显式地指明调用的是 `A` 和 `B` 类的析构函数,而不是 `C` 类的析构函数。否则,会发生递归调用,导致程序崩溃。 当程序结束时,析构函数的输出应该是: ``` Destructing C Destructing B Destructing A ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值