简体   繁体   中英

When virtual destructor is not needed even there is a virtual function, Why?

It says that if there is a virtual function, it is a good practice to have a virtual destructor. However, if the object is created on the stack but not on heap, do we still need to do that?

Regards,

Strictly speaking no - the virtual destructor is only necessary if the object will be destroyed via a pointer to reference to a base object.

If the static type at destruction time is the actual type of the object, then the correct dtor will be called regardless of whether it's virtual or not.

But if a class has virtual functions, the reason for that is generally so that it can be accessed through a pointer or reference to one of the objects bases. If the object is going to be destroyed through that mechanism, then having a virtual dtor will ensure the correct one is called. And if you have a virtual function, making the dtor virtual comes at next to no cost.

Yes since someone else could write new code that creates your object on the heap. It would be bad practice for your class to assume that it is always going to be created on the stack...

If you write an object with a virtual method, it is expected that you will use it through an interface/base object.

And it is half-expected you will own this object through a pointer (or a smart pointer). In that last case, you need the virtual destructor.

As most of the time, your code will be used by others, you can't predict they won't use the object through its base pointer... In fact, one day, you will perhaps use it this way, too...

Now, in your case, your object is created on the stack, which means that the compiler knows its type statically. Thus, when the object will be destroyed, the right destructor will be called directly, causing zero overhead.

Conclusion: As you said, it's simple good practice, and considering the limited (or zero) cost of a virtual destructor in most cases, it should be upheld.

Simple rule:

Provide either a public virtual destructor or a protected non-virtual destructor for each class that has virtual methods.

If instances of your class are meant to be deleted through a pointer to the base then the destructor must be virtual. If you class is not meant to be deleted through base pointers then making the destructor protected will block external code from deleting through a base pointer.

Note that you can use polymorphic behavior without deleting through base pointers: when you pass the object by reference or pointer but the lifetime is handled always at the most derived type, or using constructs like shared_ptr :

class base {
protected:
   ~base() {}
   virtual void f();
};
class derived : public base {
public:
   void f();
}; 
int main()
{
   shared_ptr<base> sp( new derived );

   base *b = new derived;
   //delete b; // compile time error: cannot access ~base
               // if it was allowed it would be UB
   delete static_cast<derived*>(b); // correct (static_cast is ok, we know the type)

} // sp goes out of scope: delete at ´derived´ level

One of the aims of OOP is code-reuse. So while you may be allocating objects on the stack at present, that may not always be the case under re-use and maintenance or in a team development environment.

It is generally a trivial overhead that significantly increases the utility, reusability and safety of your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM