6

Why you don't need virtual base destructor with smart pointers

 2 years ago
source link: https://blog.the-pans.com/why-you-dont-need-virtual-destructor-with-smart-pointers/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Menu

Why you don't need virtual base destructor with smart pointers

Lu Pan | 24 May 2021 | 1 min read
Why you don't need virtual base destructor with smart pointers

struct Foo {
    // virtual ~Foo() {};
    int a;
};

struct Bar : public Foo {
    ~Bar() {std::cout << "bar dtor" << std::endl;};
};

int main() {
    std::shared_ptr<Foo> f = std::make_shared<Bar>();
    //Foo* f = new Bar();
    return 0;
}
123456789101112131415

In this example, the shared_ptr version would work as you expect. The raw pointer version will, however, not call Bar's destructor because Foo's dtor is not declared virtual. The question is why the shared_ptr version works?

Smart pointers work by managing a separate control block. It not only stores a ref count in the control block but also a deleter, a callable that gets called when ref count reaches zero. Multiple shared_ptrs of the same underlying resource must share the control block.

In the example above, the deleter of the control block is set when a shared_ptr<Bar> was created. Hence the deleter will always delete a Bar object, calling Bar's destructor, no matter what happens. It has nothing to do with virtual dispatch. Hence it doesn't require Foo to have a virtual destructor.

libc++'s implementation

Let's take a look at libc++'s implementation for the aforementioned behavior.

Notice how it always takes the pointer type and use that to create the deleter here https://github.com/llvm/llvm-project/blob/main/libcxx/include/__memory/shared_ptr.h#L670. This means the following would work as expected,

auto f = std::shared_ptr<Foo>(new Bar());

Tags: c++ Lu Pan

Show Comments

How `AUTO_INCREMENT` works on MySQL

You have created tables with AUTO_INCREMENT. Something like CREATE TABLE user…


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK