2

使用するヘッダーを含むサードパーティのライブラリが提供されます。現在、このライブラリにはクラス「Base」があります。このクラスの問題は、仮想デストラクタがないことです。サードパーティのコードを持っていないので、そこで変更を行うことはできません。

これを使用していくつかの派生クラスを作成し、オブジェクトが削除されたときにオブジェクトが適切にクリーンアップされるようにするように言われました。どうすればこれを達成できますか?


返信ありがとうございます。選択肢が 2 つしかないようです。

1) 派生クラスに仮想デストラクタを配置する 2) コンポジションを使用する。

私はアプローチ番号1を取ることを計画しています。仮想デストラクタを持つラッパー派生クラスを持つことを計画しています。そして、このラッパー派生クラスを使用して、さらに派生させます。以下はコードです。

//++ THIRD PARTY HEADER
class base
{
public:
    ~base(){ }
};
//-- THIRD PARTY HEADER



//++ MY CODE
// wrapper polymorphic base.
class polymorphic_base
{
public:    
    virtual ~polymorphic_base() { }
};

class derived1 : polymorphic_base
{
/// derived 1
};

class derived2 : polymorphic_base
{
/// derived 2
}


void foo(polymorphic_base *pb)
{
    // use pb
    // use pb
    delete pb;
}


//-- MY CODE

このアプローチで問題ないかどうか教えてください。

4

2 に答える 2

2

派生クラスのデストラクタがpublic非仮想である場合、サード パーティの実装者は、そのクラスが多態的な継承に使用されることを望んでいないことを意味します。

実装計画に、基本クラス ポインターが指す派生クラスのオブジェクトを削除するシナリオがある場合、virtualデストラクタを持たない基本クラスは未定義の動作につながります。
実装計画に上記のシナリオがない場合でも、問題なくクラスから派生できます。

最初のケースでは、この基本クラスのコードがないため、大失敗を乗り越えることはできません。あなたができる最善のことは、has-a関係ではなくis-a関係を考慮し、それがあなたのために機能するようにすることです.

于 2012-12-30T05:59:52.970 に答える
0

Baseデストラクタが非仮想の場合、サポートする必要がある場合はdelete、運Base*が悪いだけです。

そうでなければ、

「オブジェクトが削除されたときにオブジェクトが適切に消去されることを確認してください」

派生クラスに仮想デストラクタを追加するだけDerivedです。

しかし、要件が本当に、文字通り「オブジェクトが削除されたとき」であると確信していますか? より良い方法は、動的割り当てを禁止することです。new割り当て関数 (たとえば、アクセシビリティを制限する) など、 -expression が必要とするものを実質的に使用不可能にすることによってコードで行うことができます。また、動的割り当てがサポートされていないことをドキュメントに記載するだけで、さらに簡単に行うことができます。 .

からクラスを派生させる目的が何であるかを明確にすることができれば、さらに良い解決策があるかもしれませんBase。クラスの派生は必要ないかもしれません。Baseたぶん、あなたはメンバーとやり遂げることができます。

于 2012-12-30T06:21:01.820 に答える