Since boost::/std::shared_ptr
have the advantage of type-erasing their deleter, you can do nice things like
#include <memory>
typedef std::shared_ptr<void> gc_ptr;
int main(){
gc_ptr p1 = new int(42);
gc_ptr p2 = new float(3.14159);
gc_ptr p3 = new char('o');
}
And this will correctly delete all pointer thanks to the correct deleter being saved.
If you ensure that every implementation of your interface always gets created with shared_ptr<Interface>
(or make_shared<Interface>
), do you actually need a virtual
destructor? I would declare it virtual
anyways, but I just want to know, since shared_ptr
will always delete the type it was initialized with (unless another custom deleter is given).
Virtual base class destructors are "best practice" - you should always use them to avoid (hard to detect) memory leaks. Using them, you can be sure all destructors in the inheritance chain of your classes are beeing called (in proper order).
Overview. A virtual destructor is used to free the space which is assigned to the object of the derived class while we are trying to delete the instances of the base class using a pointer object of the base class.
All the instances point to the same object, and share access to one "control block" that increments and decrements the reference count whenever a new shared_ptr is added, goes out of scope, or is reset. When the reference count reaches zero, the control block deletes the memory resource and itself.
I would still follow the common rule for classes that are meant to be derived:
Provide either a public virtual destructor or a protected non-virtual destructor
The reason is that you cannot control all of the uses, and that simple rule means that the compiler will flag if you try to delete
through the wrong level in the hierarchy. Consider that shared_ptr
does not guarantee that it will call the appropriate destructor, only that it will call the destructor of the static type that was used as argument:
base* foo();
shared_ptr<base> p( foo() );
If base
has a public non-virtual destructor and foo
returns a type that derives from base
, then shared_ptr
will fail to call the correct destructor. If the destructor of base
is virtual, everything will be fine, if it is protected, the compiler will tell you that there is an error there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With