开发者

C++ destructors as virtual functions?

I just read recently that its a good practice to implement C++ destructors as virtual functions[1]. Why is this so? Is this a general good practice? If not, in what conditions/case开发者_C百科s is a destructor to be made a virtual function?

Reference

  1. https://www.blackhat.com/presentations/bh-usa-07/Afek/Whitepaper/bh-usa-07-afek-WP.pdf


Herb Sutter discusses this subject in great detail in his article "Virtuality." Guideline #4 states "A base class destructor should be either public and virtual, or protected and nonvirtual."

If your class isn't designed or intended to be used as a base class then there is no reason to declare it with a virtual destructor.


If a base class has a destructor and it is NOT virtual, then any child class's destructor will not be called if delete is invoked on the base class's pointer.

This can result in memory leaks.

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;
}

This will result in:

Triangle constructor called
Shape constructor called
About to call delete
Shape destructor called

Any resources that should be deallocated in the triangles destructor has now leaked.


From Effective C++ by Scott Meyers - "The rule for giving base classes virtual destructors applies only to polymorphic base classes — to base classes designed to allow the manipulation of derived class types through base class interfaces."

It is most likely that if you have any virtual functions in your base class then the base class destructor must be made virtual.

Classes not designed to be base classes or not designed to be used polymorphically should not declare virtual destructors


When your class has a virtual destructor, then you ensure that destructors in derived classes will be called.


Arguably if your entire class hierarchy is POD or has nothing for the destructors to do, you might get away with not having a virtual destructor. However, as soon as you want to derive other classes from your class and want to use them polymorphically through pointer/reference-to-base, you will have virtual functions anyway, so there is little overhead adding a virtual destructor, and you never know who will be inheriting from you. As soon as any derived class requires a non-trivial destructor and may be refered to via pointer-to-base, you must have a virtual destructor.

Rule of thumb: if you have any virtual functions, add a virtual destructor.

(The point here is that if you have no virtual functions, then there will be no way to use derived classes polymorphically, so it will be less likely that an illegitimate child class that requires non-trivial destruction will be deleted via a base class pointer. It could still be done, it's just less likely.)


http://blogs.msdn.com/b/oldnewthing/archive/2004/05/07/127826.aspx

In this day and age, I think you should make all methods virtual and then think which ones do not need to be.

OK, yeah, I've done most of my OOP in Java.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜