我有一个基类和派生类的层次结构。基类有一个虚函数,被派生类重写。
class Base
{
public:
~Base();
virtual void other_functionality() = 0;
};
class Derived : public Base
{
public:
~Derived ();
void other_functionality() {//some code};
};
现在,如果我喜欢这样:
int main()
{
Base * P = new Derived ();
delete p;
return 0;
}
它给出了错误: 删除具有非虚析构函数的多态类类型的对象。
但是使用unique_ptr它会在没有警告的情况下通过。
int main()
{
std::unique_ptr<Base> p;
p.reset(new Derived ());
return 0;
}
我知道我是否使用虚拟析构函数。将解决与裸指针的警告。但问题仍然存在 - 为什么缺少虚拟析构函数会显示裸指针而不是unique_ptr。
首先,当基类没有虚拟析构函数时,通过基指针删除派生对象是未定义的行为。编译器不需要诊断未定义的行为......
话虽如此,使用std::unique_ptr
时出现此警告的原因很可能是由于GCC does not report warnings that would appear in system headers。
我找不到链接,但我确实在GCC bug数据库中看到了这个在线的讨论。
警告是在实际的delete
表达式上发出的。在unique_ptr
的情况下,delete
在系统头文件中调用。
根据该bug报告中的讨论,实现C ++系统库需要各种各样的妥协,从而导致各种警告。因此,警告在系统标头内受到限制。这就是你不会看到预期警告的原因。
更新:就在这里,直接来自马的嘴:
https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html
声明操作系统和运行时库接口的头文件通常不能严格符合C语言编写。因此,GCC会在系统头文件中给出代码特殊处理。 GCC正在处理系统标题时,除了'#warning'(请参阅诊断)生成的警告之外的所有警告都将被禁止。