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。     

要回复问题请先登录注册