C++子类的智能指针赋值给父类的智能指针,析构函数不是虚函数,也能正确执行析构

C++子类的智能指针赋值给父类的智能指针,析构函数不是虚函数,也能正确执行析构

正如大家都知道,如下代码片段:

BaseNode *pp1 = new BinaryTreeNode(); // BaseNode 是 BinaryTreeNode的父类
delete pp1;

如果想要在delete回收pp1指针时正确析构对象,即:先执行BinaryTreeNode()函数,再执行BaseNode()函数。我们需要在BaseNode类中将~BaseNode()函数定义为虚函数。如下所示:

class BaseNode {
public:
  BaseNode();

  virtual ~BaseNode();
};

class BinaryTreeNode : public BaseNode {
public:
  virtual ~BinaryTreeNode();
};


int main() {
  cout << "使用裸指针" << endl;
  BaseNode *pp1 = new BinaryTreeNode();
  delete pp1;
  return 0;
}

BaseNode::BaseNode() {}

BaseNode::~BaseNode() {
  cout << "~BaseNode" << endl;
}

BinaryTreeNode::~BinaryTreeNode() {
  cout << "~BinaryTreeNode" << endl;
}

执行结果:

使用裸指针
~BinaryTreeNode
~BaseNode

如我们所愿,在将~BaseNode()函数定义为虚函数后,析构函数正确执行。

如果~BaseNode()函数不是虚函数,使用智能指针shared_ptr。在指针析构的时候是否析构函数正确执行呢?

实验的代码如下:

class BaseNode {
public:
  BaseNode();

  ~BaseNode();
};

class BinaryTreeNode : public BaseNode {
public:
  ~BinaryTreeNode();
};


int main() {
  {
    cout << "使用智能指针" << endl;
    std::shared_ptr<BaseNode> p1;
    p1 = std::shared_ptr<BinaryTreeNode>(new BinaryTreeNode());
  }

  cout << "使用裸指针" << endl;
  BaseNode *pp1 = new BinaryTreeNode();
  delete pp1;
  return 0;
}

BaseNode::BaseNode() {}

BaseNode::~BaseNode() {
  cout << "~BaseNode" << endl;
}

BinaryTreeNode::~BinaryTreeNode() {
  cout << "~BinaryTreeNode" << endl;
}

结果如下:

使用智能指针
~BinaryTreeNode
~BaseNode
使用裸指针
~BaseNode

可以看出使用智能指针时,即便父类的析构函数不是虚函数,也能够正确析构。

注意:

虽然智能指针能够在父类析构函数不是虚函数的情况之下正确析构,但实际使用过程中如果遇到“子类指针要赋值给父类”的情况,最好将父类的析构函数定义为虚函数。除非你的代码对性能要求非常高,你需要仔细衡量一下,因为定义虚函数会引入的虚函数表,不仅会增加编译后的文件的大小,也会因为每次实例化该对象都会额外分配虚函数表的内存空间,增加内存消耗。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值