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の部分的な知識だけでこの条件を満たすことが可能かどうかはわかりません。ベンダーのSDKでは、手間のかかる作業のほとんどがdllまたはライブラリオブジェクトで行われます。

私のビルド環境は、gppを使用したEclipseJunoです。

Googleでエラーメッセージを検索しましたが、このエラーのインスタンスは見つかりませんでした。

それで、ベンダーコードのブラックボックス部分を変更できない場合、私のオプションは何ですか?

makeプロセス中に失敗するコードは次のとおりです。

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のバグです。基本クラスとして使用されるクラスには、仮想デストラクタが必要です。そうしないと、派生クラスインスタンスのベースへのポインタを削除しても、派生クラスのデストラクタは呼び出されません。

それを回避する1つの方法は、ベースへのポインタを削除しないことです。代わりに、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型のLValueが必要な場所を除いて、NotGoodBaseを使用できる場所であればどこでもUseThisAsBase型のポインターを使用できるはずです。

于 2012-10-21T04:52:12.667 に答える
-4

実際、コンパイルとプログラムから-Werrorスイッチを削除しました。

現在、メッセージは単なる警告です。

ベンダーにバグレポートを送信します。

于 2012-10-24T18:36:20.497 に答える