17

当我尝试从第三方 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 或库对象中完成的。

我的构建环境是带有 gpp 的 Eclipse Juno。

我在 Google 中搜索了错误消息,但没有找到此错误的任何实例。

那么,如果我无法修改供应商代码的黑匣子部分,我有什么选择?

这是在制作过程中失败的代码:

delete pData->unit;
4

6 回答 6

16

坏消息,我害怕。您不应将该类用作基类。太多的限制和陷阱。你可能会侥幸逃脱,但为什么要冒险呢?向库供应商提交错误报告。

如果您不需要多态指针,请在您的类中包含该类型的对象,并委托您想要继承的成员函数。

class my_class {
private:
    evil_class evil;
public:
    virtual ~my_class() {/* stuff */}
    virtual int member() { return evil.member(); }
};
于 2012-10-21T04:37:52.943 回答
11

好吧,这是第三方 SDK 中的错误。任何用作基类的类都应该有一个虚拟析构函数。否则,当您删除指向派生类实例的基类的指针时,派生类的析构函数将不会被调用。

一种解决方法是不删除指向基的指针。相反,使用 dynamic_cast 获取指向派生类的指针(如果有许多从该基类派生的类,这可能会很不方便)。

于 2012-10-21T04:23:42.627 回答
4

当基类具有虚拟成员函数但没有虚拟 dtor 时会产生此警告。这是一个错误。如果您没有代码,那么除了确保手动取消分配子类中的任何资源外,您无能为力。就像在cleanup()您确保在删除对象之前手动调用的自定义成员函数中一样。

另一种选择是static_cast它到正确的类。请注意dynamic_cast(这会产生运行时开销并需要 RTTI)是不需要的。在这种情况下,编译器可以在编译时很好地导出类型关系。

当然,如果该对象在不属于您代码的其他地方被删除,那么您就不走运了。在这种情况下,请确保您的子类不分配任何东西。这样即使没有调用析构函数也不会泄漏。

于 2012-10-21T04:26:30.940 回答
4

在这种情况下,您需要将虚拟析构函数添加到您的类中,而不是从此处删除编译标志。

例如。对于类,Myclass此错误即将到来,然后添加

virtual ~Myclass(){}

试试这个灵魂,它会很好用。

于 2017-05-23T07:36:00.363 回答
3

您不能安全地使用指向基类的指针,除非它在基类上声明了虚拟析构函数。由于这是一个供应商库,您不能添加所需的虚拟析构函数。

如果库本身不创建该对象的子类,您可以通过为该对象声明一个子类并将该对象用作基类来获得所需的效果。

class NotGoodBase {
 ~NotGoodBase(); // Non-virtual destructor.  Possibly added by compiler.
};

class UseThisAsBase : public NotGoodBase {
 virtual ~UseThisAsBase(); // Virtual destructor.
};

您应该能够在可以使用 NotGoodBase 的任何地方使用 UseThisAsBase 类型的指针,除了需要具有 NotGoodBase 类型的 LValue 的地方,例如赋值或通过引用传递变量时。

于 2012-10-21T04:52:12.667 回答
-4

实际上,我从编译和程序编译中删除了 -Werror 开关。

现在,这些消息只是警告。

我将向供应商发送错误报告。

于 2012-10-24T18:36:20.497 回答