当裸指针显示时,派生类的基类保持引用的std :: unique_ptr在gcc编译器中不显示警告。为什么?

问题描述 投票:34回答:2

我有一个基类和派生类的层次结构。基类有一个虚函数,被派生类重写。

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。

c++ c++14 gcc-warning
2个回答
40
投票

首先,当基类没有虚拟析构函数时,通过基指针删除派生对象是未定义的行为。编译器不需要诊断未定义的行为......

话虽如此,使用std::unique_ptr时出现此警告的原因很可能是由于GCC does not report warnings that would appear in system headers


21
投票

我找不到链接,但我确实在GCC bug数据库中看到了这个在线的讨论。

警告是在实际的delete表达式上发出的。在unique_ptr的情况下,delete在系统头文件中调用。

根据该bug报告中的讨论,实现C ++系统库需要各种各样的妥协,从而导致各种警告。因此,警告在系统标头内受到限制。这就是你不会看到预期警告的原因。

更新:就在这里,直接来自马的嘴:

https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html

声明操作系统和运行时库接口的头文件通常不能严格符合C语言编写。因此,GCC会在系统头文件中给出代码特殊处理。 GCC正在处理系统标题时,除了'#warning'(请参阅诊断)生成的警告之外的所有警告都将被禁止。

© www.soinside.com 2019 - 2024. All rights reserved.