我们知道, 如果有虚函数,则基类析构函数也应标记为虚函数,否则, 如果我们希望使用基类指针删除 deleted
基类析构函数,则在 使用基类指针进行 显式 删除 时,这是未定义的行为。 虚拟的,否则是未定义的行为。
例如,
struct Base {
virtual void greet() { std::cout << "base\n"; }
};
struct Derived : public Base {
virtual void greet() override { std::cout << "derived\n"; }
};
呼叫
Base *b = new Derived;
b->greet();
delete (b);
当-Wdelete-non-virtual-dtor时,clang(类似的gcc)将发出这样的警告:
delete called on 'Base' that has virtual functions but non-virtual destructor
但是他们两个都没有报告关于智能指针的警告:
std::unique_ptr<Base> sb = std::make_unique<Derived>();
// std::unique_ptr<Base> sb = std::unique_ptr<Derived>(new Derived);
sb->greet();
我想这仍然会导致不确定的行为,对吗?
是的,它仍然是未定义的行为。问题在于delete
调用发生在std::default_delete
系统标头内部的内部。默认情况下,编译器不会为系统头文件中的代码生成警告。
如果通过-Wsystem-headers
,则会看到警告。不幸的是,它被埋在一堆其他警告中。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句