When should your destructor be virtual? [duplicate

2019-01-07 07:17发布

Possible Duplicate:
When to use virtual destructors?

When should your C++ object's destructor be virtual?

6条回答
一夜七次
2楼-- · 2019-01-07 07:26

If you will (or even might) destroy objects of a derived class through a base class pointer, you need a virtual destructor.

I take the approach that if I'm going to derive from a class AT ALL, then it shall have a virtual destructor. There are effectively no cases in the code I write where the performance implications of a virtual destructor matter, and even if it's not actually needed today, it might end up needing it in the future when the class is modified.

Basically: Put virtual on all base class destructors unless you have a good, well-thought out reason not to.

That's just another rule of thumb, but it's one that keeps you from making later mistakes.

查看更多
何必那么认真
3楼-- · 2019-01-07 07:29

From Stroustrup's C++ Style and Technique FAQ:

So when should I declare a destructor virtual? Whenever the class has at least one virtual function. Having virtual functions indicate that a class is meant to act as an interface to derived classes, and when it is, an object of a derived class may be destroyed through a pointer to the base.

Lots of additional info on when your destructor should be virtual on the C++ FAQ. (thanks Stobor)

What is a virtual member? From the C++ FAQ:

[20.1] What is a "virtual member function"?

From an OO perspective, it is the single most important feature of C++: [6.9], [6.10].

A virtual function allows derived classes to replace the implementation provided by the base class. The compiler makes sure the replacement is always called whenever the object in question is actually of the derived class, even if the object is accessed by a base pointer rather than a derived pointer. This allows algorithms in the base class to be replaced in the derived class, even if users don't know about the derived class.

The derived class can either fully replace ("override") the base class member function, or the derived class can partially replace ("augment") the base class member function. The latter is accomplished by having the derived class member function call the base class member function, if desired.

查看更多
We Are One
4楼-- · 2019-01-07 07:29

Always.

Unless I'm really concerned with the storage and performance overhead of a vtable, I always make it virtual. Unless you have a static analysis tool to verify for you that your destructor is virtual in the right cases, it's not worth making a mistake and failing to make a virtual destructor when it's needed.

查看更多
一纸荒年 Trace。
5楼-- · 2019-01-07 07:31
  1. You need virtual destructor when at least one of class methods is virtual.

This is because the reason for virtual method is that you want to use polymorphism. Meaning you will call a method on the base class pointer and you want the most derived implementation - this is the whole point of polymorphism.

Now if you did not have virtual destructor and through the pointer to base class you call destructor you end up calling base class destructor. In this case you want polymorphism to work on your destructor as well, e.g. through calling destructor on your base class you want to end up calling destructor of your most derived class not your base class.

class A
{
   virtual void f() {}
   ~A() {}
}

class B : public A
{
   void f() {}
   ~B() {}
}

A * thing = new B();
thing->f(); // calls B's f()
delete thing; // calls ~A(), not what you wanted, you wanted ~B()

having ~A() virtual turns on polymorphism

virtual ~A() {}

So when you now call

delete thing;

~B() will be called.

You would declare virtual destructors when you design class as an interface e.g. you expect it to be extended or implemented. A good practice in that case is to have a interface class (in the sense of Java interfaces) with virtual methods and virtual destructor and then have concrete implementation classes.

You can see that STL classes don't have virtual destructors so they are not supposed to be extended (e.g. std::vector, std::string ...). If you extend std::vector and you call destructor on base class via pointer or reference you will definitely not call your specialized class destructor which may lead to memory leaks.

查看更多
戒情不戒烟
6楼-- · 2019-01-07 07:34

I've recently come to conclude that the fully correct answer is this:

Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.

And of course Herb Sutter gives the rationale to his claim. Note that he does go beyond the usual answers "when someone will delete a derived-class object via a base-class pointer" and "make your destructor virtual if your class has any virtual functions".

查看更多
欢心
7楼-- · 2019-01-07 07:43

A base class object should have a virtual destructor, when it is necessary for the base class to do its own cleanup. This is to say, if you have allocated resources in the base class it is necessary for the base class to cleanup, by declaring its destructor virtual you guarantee that this cleanup will be done (assuming you wrote the cleanup correctly).

In general, methods can be defined virtual in a base class, this will allow derived classes to override the virtual methods, implementing their own derived specific implementation. I find this is most clearly demonstrated with a simple example. Say we have a base class 'Shape', now all derived classes may be required to have the ability to draw. The 'Shape' object will not know how to draw classes derived from it, so in the 'Shape' class we define a virtual draw function. ie (virtual void draw();). Now in each base class we can override this function, implementing specific drawing code (ie. a square is drawn differently from a circle).

查看更多
登录 后发表回答