为了账号安全,请及时绑定邮箱和手机立即绑定

没有学不会的C++:虚析构函数和智能指针

标签:
C++

虚析构函数

当我们想在程序中实现多态时,我们经常会这样做:

#include <iostream>
using namespace std;
class Dog {
public:
  Dog() {}
  ~Dog() { cout << "Dog destroy\n";}
};

class YellowDog : public Dog {
public:
  YellowDog() {}
  ~YellowDog() { cout << "YellowDog destroy\n";}
  static Dog* createDog() { return new YellowDog(); }
};

即用工厂类或工厂方法来创建具体的对象,而在运行时通过对基类(这里是Dog)的指针或引用来实现对不同子类(这里是YellowDog)的调用,这样我们就实现了「多态」。不过,上面代码是有问题的,你可以看下面代码的输出:

int main(int argc, char** argv) {
  Dog* dog = YellowDog::createDog();
  delete dog;
  return 0;
}
----<output>----
Dog destroy

从输出结果可以看出,delete dog 时,只调用了基类的析构函数,而子类对象没有被析构,此时很可能会发生内存泄露,为了避免这种情况,我们需要在基类析构函数前加上 virtual 关键字,如下

virtual ~Dog() { cout << "Dog destroy\n"; }

接着重新编译后再运行程序,便可以看到子类对象被如期析构了

----<output>----
YellowDog destroy
Dog destroy

用智能指针 shared_ptr 实现动态析构

从 C++ 11 起,通过 shared_ptr 你同样可以实现动态析构,shared_ptr 定义在头文件 <memory>

template< class T > class shared_ptr;

下面我们就来看下智能指针的版本

class Dog {
public:
  Dog(){}
  ~Dog() { cout << "Dog destructor" << endl; }
};

class YellowDog : public Dog {
public:
  YellowDog() {}
  ~YellowDog() { cout << "YellowDog destructor" << endl; }

  static shared_ptr<Dog> createDog() {
      return shared_ptr<YellowDog>(new YellowDog());
  }
};

int main() {
    shared_ptr<Dog> p = YellowDog::createDog();
    return 0;
}

从输出中可以看到虽然 Dog 类中的析构函数没有声明 virtual,但 YellowDog 的析构函数仍然被顺利调用了。

注意:STL 中的所有类都没有 virtual 析构函数,所以当你从 STL 中派生子类时,要尽可能的使用 shared_ptr

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消