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