如何解决C ++析构函数作为虚函数?
| 我最近才读到,将C ++析构函数实现为虚函数是一种很好的做法[1]。为什么会这样呢?这是一般的好习惯吗?如果不是,则在什么情况下将析构函数设为虚函数? 参考 https://www.blackhat.com/presentations/bh-usa-07/Afek/Whitepaper/bh-usa-07-afek-WP.pdf解决方法
如果基类具有析构函数,并且不是虚拟的,则如果在基类的指针上调用delete,则不会调用任何子类的析构函数。
这可能会导致内存泄漏。
class Shape
{
public:
Shape()
{
cout << \"Shape constructor called\" << endl;
}
// This destructor should be virtual!
~Shape()
{
cout << \"~Shape destructor called\" << endl;
}
};
class Triangle : public Shape
{
public:
Triangle()
{
cout << \"Triangle constructor called\" << endl;
}
~Triangle()
{
cout << \"Triangle destructor called\" << endl;
}
}
int main(int argc,char* argv[])
{
Shape* pShape = new Triangle();
cout << \"About to call delete\" << endl;
delete pShape;
}
这将导致:
三角构造函数称为
形状构造函数称为
即将通话删除
形状析构函数称为
现在,应该在三角形析构函数中重新分配的所有资源都已泄漏。
, 赫伯·萨特(Herb Sutter)在他的文章“虚拟性”中对此主题进行了详细讨论。准则4中指出:“基类析构函数应该是公共的和虚拟的,或者是受保护的并且是非虚拟的。”
如果您的类不是设计为或不打算用作基类,则没有理由使用虚拟析构函数对其进行声明。
, 斯科特·迈耶斯(Scott Meyers)的《有效C ++》摘录-“为基类提供虚拟析构函数的规则仅适用于多态基类-旨在允许通过基类接口操纵派生类类型的基类。”
如果您的基类中有任何虚函数,则很有可能必须将基类析构函数设为虚拟。
未设计为基类或未设计为多态使用的类不应声明虚拟析构函数
, 当您的类具有虚拟析构函数时,请确保将调用派生类中的析构函数。
, 可以说,如果您的整个类层次结构是POD或没有任何可用于析构函数的事情,那么您可能会因为没有虚拟析构函数而脱身。但是,一旦您想从您的类派生其他类并希望通过指针/对基的引用来多态使用它们,无论如何您将拥有虚拟函数,因此添加虚拟析构函数的开销很小,而且您永远不会知道谁将从你那里继承。一旦任何派生类都需要一个非平凡的析构函数,并且可以通过指向基础的指针进行引用,则您必须具有一个虚拟析构函数。
经验法则:如果您有任何虚拟函数,请添加一个虚拟析构函数。
(这里的要点是,如果您没有虚函数,那么将无法多态使用派生类,因此不太可能通过基类指针删除需要非平凡破坏的非法子类。 。仍然可以完成,可能性很小。)
, http://blogs.msdn.com/b/oldnewthing/archive/2004/05/07/127826.aspx
在当今时代,我认为您应该将所有方法虚拟化,然后再考虑不需要使用哪种方法。
好的,是的,我已经用Java完成了大部分OOP。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。