We know that
if there are virtual functions then the base class destructor should be marked as virtual as well, otherwise it is undefined behavior when explicitly
if we hope to delete derived object with base class pointer the base destructor should be marked as virtual, otherwise it is undefined behavior. deleted
with base class pointer
For example,
struct Base {
virtual void greet() { std::cout << "base\n"; }
};
struct Derived : public Base {
virtual void greet() override { std::cout << "derived\n"; }
};
call
Base *b = new Derived;
b->greet();
delete (b);
clang(gcc similarly) will emit such a warning when -Wdelete-non-virtual-dtor :
delete called on 'Base' that has virtual functions but non-virtual destructor
But neither of them report warnings for smart pointers :
std::unique_ptr<Base> sb = std::make_unique<Derived>();
// std::unique_ptr<Base> sb = std::unique_ptr<Derived>(new Derived);
sb->greet();
I guess this still leads to undefined behavior, right?
Yes, it's still undefined behavior. The problem is that the delete
call happens inside std::default_delete
, which is inside a system header. By default, the compiler doesn't generate warnings for code in system headers.
If you pass -Wsystem-headers
, you'll see the warning. Unfortunately, it's buried inside a pile of other warnings.
Not mentioned yet by the other answers:
This problem only exists for unique_ptr
, not for the shared_ptr
.
Both of these smart pointers can have custom deleters; however unique_ptr
defaults to deleting the base pointer, and shared_ptr
defaults to deleting the derived pointer (if you used make_shared<Derived>
or equivalent).
Another way to solve the problem is to supply your own custom deleter for unique_ptr
that deletes the derived pointer. This might be a good solution for cases where you want to avoid the overhead of introducing a vtable.
Further reading: unique_ptr
deleter , shared_ptr
deleter
截至铿锵r312167 (大约半年内发布时将处于clang 6.0中),clang的-Wdelete-non-virtual-dtor
警告将-Wdelete-non-virtual-dtor
发出警告。
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.