Effective C++ 条款7 多态基类声明virtual析构函数

  • 通过用户去调用工厂方法创建对象,然后delet是不安全的---见条款13
  • 如何修改factory函数避免调用的错误?---见条款18
  • 删除指向派生类的基类对象指针可能带来内存泄漏。 

  • 删除指向派生类的基类对象,只会调用基类析构函数。
#include <iostream>
using namespace std;
 
class Base{
  public:
    ~Base() {cout<<"~B"<<endl;}
};
 
class Derived:public Base{
  public:
    ~Derived() {cout<<"~D"<<endl;}
};
 
int main (){
  Base *b = new Derived; //注意这里
  delete b;
}

查看打印日志:

~B

可见删除指向派生类的基类对象,代表delete只删除了父类,并没有删除子类的相关内存,会产生内存泄漏。所以在多态的使用过程中,delete(指向父类的子类对象)需要格外注意是否会没有释放子类或者父类。

  • 正常的调用:delete指向派生类的派生类对象
#include <iostream>
using namespace std;
 
class Base{
  public:
    ~Base() {cout<<"~B"<<endl;}
};
 
class Derived:public Base{
  public:
    ~Derived() {cout<<"~D"<<endl;}
};
 
int main (){
  Derived *d = new Derived; //注意这里
  delete d;
}

子类指向子类指针,查看打印日志:

~D

~B

可以得知,delete子类的析构顺序:是先释放子类,在释放父类。

这是我们期望的结果,所以没啥问题。。。

  • 通过基类析构函数加上virtual避免delete Base类带来内存泄漏

对于第一种情况,如何去规避呢?  需要将父类的析构函数定义为virtual

#include <iostream>
using namespace std;
 
class Base{
  public:
    virtual ~Base() {cout<<"~B"<<endl;}
};
 
class Derived:public Base{
  public:
    ~Derived() {cout<<"~D"<<endl;}
};
 
int main (){
  Base *d = new Derived; //注意这里
  delete d;
}

打印结果:

~D

~B

参考:C++ virtual 析构函数_zion--6135的博客-CSDN博客

  • 总结:如果一个类要用作继承的基类,那么他的析构函数应该声明为virtual
  • 如果这个类不希望被当作基类使用,析构函数不该加上virtual

  • 如果一个类没有virtual函数,代表这个类不希望被用作Base class,如果这样还是把析构函数用作virtual,这会带来坏处:因为每一个类中的只要有virtual函数,那么就会产生一个vptr(虚函数指针),这会带来额外的内存开销。
  •  为抽象类定义一个pure virtual析构函数

  • pure virtual函数导致不能实例化此类。
  • 当希望拥有一个抽象类,但没有虚函数,就可以将析构函数定义为pure virtual,本质上还是基类析构函数加上virtual避免内存泄漏,只不过在一个没有虚函数的抽象类上,这个虚析构函数是 pure virtual析构函数。如下的  virtual ~AWOV() = 0;
#include <iostream>
using namespace std;
 
//abstract class
class AWOV
{
public:
	virtual ~AWOV() = 0;
};
 
AWOV::~AWOV(){
    printf("AAA\n");
}

//derived class
class derived :public AWOV {
public:
~derived(){
    printf("BBB\n");
}
};
 

int main (){
	AWOV* p = new derived;
	delete p;      
    printf("CCC\n");
}

打印结果:

BBB
AAA
CCC

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值