可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am getting the following error when I try to compile some code from a Third-party 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*
I do not know if its possible to satisfy this condition with only partial knowledge of the Vendor's SDK, where most of the heavy lifting is done in a dll or library object.
My build environment is Eclipse Juno with gpp.
I searched in Google for the error message and did not find any instances of this error.
So, if I cannot modify the black box part of the vendor code, what are my options?
Here is the code that is failing during the make process:
delete pData->unit;
回答1:
Bad news, I am afraid. You should not use that class as a base class. Too many constraints and pitfalls. You might get away with it, but why risk it? File a bug report with the library vendor.
If you do not need polymorphic pointers, include an object of that type in your class, and delegate the member functions you wanted to inherit.
class my_class {
private:
evil_class evil;
public:
virtual ~my_class() {/* stuff */}
virtual int member() { return evil.member(); }
};
回答2:
Well it's a bug in the third-party SDK. Any class that is used as a base class should have a virtual destructor. Otherwise, when you delete a pointer to the base of a derived class instance, the derived class's destructor won't be called.
One way around it is to not delete pointers to the base. Instead, use dynamic_cast to get a pointer to the derived class (this might be inconvenient if there are many classes derived from that base).
回答3:
This warning is produced when the base class has virtual member functions but no virtual dtor. This is a bug. If you don't have the code, then there's nothing you can do other than making sure you're manually de-allocating any resources in your subclass. Like in a custom cleanup()
member function that you make sure to call manually before deleting the object.
Another option is to static_cast
it to the correct class. Note that dynamic_cast
(which incurs runtime overhead and requires RTTI) is not needed. The compiler can derive the type relationship just fine at compile time in this case.
Of course, if the object is deleted somewhere else that's not part of you code, then you're out of luck. In that case, make sure your subclass doesn't allocate anything. That way it's not possible to leak even when the destructor isn't being called.
回答4:
You cannot safely use a pointer to the base class, unless it has a virtual destructor declared on the base class. Since this is a vendor library, you can not add the virtual destructor needed.
If the library itself does not create subclasses of this object, you may be able to get the effect you need by declaring a subclass for this object and use that object as a base class.
class NotGoodBase {
~NotGoodBase(); // Non-virtual destructor. Possibly added by compiler.
};
class UseThisAsBase : public NotGoodBase {
virtual ~UseThisAsBase(); // Virtual destructor.
};
You should be able to use pointers of type UseThisAsBase anywhere that you could use NotGoodBase, except places where you need to have an LValue of type NotGoodBase, such as an assignment or when passing a variable by reference.
回答5:
In this scenario you need to add virtual destructor to your class rather than removing compilation flag from here.
eg. for class Myclass
this error is coming then add
virtual ~Myclass(){}
Try this soultion, it will work fine.
回答6:
Actually, I removed the -Werror switch from the compile and the program compiled.
Now, the messages are just warnings.
I will send a bug report to the vendor.