我收到以下错误,当我尝试从第三方SDK编译一些代码。
*Description Resource Path Location Type
deleting object of polymorphic class type ‘Vendor_sys::VendorCode’ which has non-virtual destructor might cause undefined behaviour [-Werror=delete-non-virtual-dtor] PnServer.cpp /PCounter line 467 C/C++ Problem*
我不知道,如果可能,只有卖方SDK的部分知识,大多数繁重的工作在一个dll或库对象做是为了满足这个条件。
我的编译环境就是Eclipse朱诺与GPP。
我在谷歌搜索的错误消息,并没有发现这个错误的任何实例。
所以,如果我不能修改供应商代码的黑盒部分,我有哪些选择?
这里是在化妆过程中出现错误的代码:
delete pData->unit;
坏消息,我很害怕。 你不应该使用这个类的基类。 太多的限制和陷阱。 你可能逃脱它,但为什么要冒险呢? 文件与库供应商的bug报告。
如果你不需要多形指针,包括输入你的类的对象,并委托你想继承的成员函数。
class my_class {
private:
evil_class evil;
public:
virtual ~my_class() {/* stuff */}
virtual int member() { return evil.member(); }
};
那么它在第三方SDK中的错误。 被用作基类中的任何类应该有一个虚拟析构函数。 否则,当你删除一个指向一个派生类实例的基础上,派生类的析构函数不会被调用。
它周围的一种方法是不会删除指针的基础。 相反,使用的dynamic_cast获得一个指向派生类(如果有从基地派生类很多,这可能是不方便)。
此警告时产生的基类有虚拟成员函数,但没有虚拟析构函数。 这是一个错误。 如果没有代码,那么还有什么可以做的比确保你手动解除分配在子类中的任何资源等。 就像在自定义cleanup()
成员函数,你一定要删除对象之前手动调用。
另一种选择是static_cast
到正确的类。 需要注意的是dynamic_cast
(这将产生运行时开销,需要RTTI)是没有必要的。 编译器可以推导出类型的关系在这种情况下,编译时间就好了。
当然,如果该对象被删除别的地方,这不是你的代码的一部分,那么你的运气了。 在这种情况下,要确保你的子类不分配任何东西。 这样,它不可能泄漏,即使析构函数没有被调用。
你不能安全地使用指针的基类,除非它对基类中声明虚析构函数。 由于这是一个供应商库,你不能添加所需的虚拟析构函数。
如果库本身不会产生这个对象的子类,你可以得到你需要通过声明此对象,并使用该对象作为基类的子类的效果。
class NotGoodBase {
~NotGoodBase(); // Non-virtual destructor. Possibly added by compiler.
};
class UseThisAsBase : public NotGoodBase {
virtual ~UseThisAsBase(); // Virtual destructor.
};
你应该能够使用类型UseThisAsBase的指针的任何地方,你可以使用NotGoodBase,除非你需要有型NotGoodBase的左值,如分配或引用传递变量时的地方。
在这种情况下,你需要虚析构函数添加到您的类,而不是从这里取出编译标志。
例如。 类Myclass
这个错误就要再加入
virtual ~Myclass(){}
试试这个soultion,它会正常工作。
其实,我删除从编译的-Werror开关和编译的程序。
现在,这些消息仅仅是警告。
我会传送给供应商的bug报告。
文章来源: How to delete an object of a polymorphic class type that has no virtual destructor