2016-03-24 3 views
1

私のシナリオでは、基本クラスを持つDLLがあります。このDLLはプラグインを読み込むことができます。各プラグインDLLは、派生オブジェクトを返すcreate関数をエクスポートします。私は、プラグインDLLからのオブジェクトが自分自身を削除することができれば好きです。別のDLLから受け取った派生オブジェクトを適切に削除するにはどうすればよいですか?

以下では、2つの方法を書き留めました。欠落している公開/非公開のステートメントは無視してください。最初の方法は、私が削除を通常どおり呼び出す必要があるので、もちろん簡単ですが、それが動作するかどうかはわかりません。 2番目の方法は、thisに派生型が必要であるため、明示的にdelete thisを実行します。

// main DLL 

class Base1 
{ 
    virtual ~Base(){} 
}; 

class Base2 
{ 
    virtual ~Base(){} 
    virtual void destroy() = 0; 
}; 

// plugin DLL without destroy 
class Derived1 : public Base1 
{ 
    Derived1() 
    { 
     m_p = new cSomeClass; 
    } 

    virtual ~Derived1() 
    { 
     delete m_p; 
    } 

    cSomeClass * m_p; 
} 

// function which is exported 
Base1 * createDerived1() 
{ 
    return new Derived1; 
} 

// plugin DLL with destroy 
class Derived2 : public Base2 
{ 
    Derived2() 
    { 
     m_p = new cSomeClass; 
    } 

    virtual ~Derived2() 
    { 
     delete m_p; 
    } 

    virtual void destroy() 
    { 
     delete this; 
    } 

    cSomeClass * m_p; 
} 

// function which is exported 
Base2 * createDerived2() 
{ 
    return new Derived2; 
} 


int main() 
{ 
    Base1 * pBase1 = createDerived1(); 
    delete pBase1; 
    pBase = nullptr; 
    // is derived object properly deleted? 

    Base2 * pBase2 = createDerived2(); 
    pBase2->destroy(); 
    pBase2 = nullptr; 
    // is derived object properly deleted? 

} 

"正しいこと"、つまり基本クラスポインタを使用して派生オブジェクトを適切に削除するのはどちらですか?

  1. deleteはオブジェクトタイプを認識しており、仮想デストラクタのためにオブジェクトタイプを正しく削除します。
  2. 派生クラスに実装されている純粋仮想破棄メソッドを記述します。
  3. Baseポインタをとり、deleteの前に動的キャストを行うcreateメソッドの横にdestroy()メソッドをエクスポートします。 (私はそれが魅力のない見つけるので、私はこのような場合のために例を書いていない。)

最初の方法は、それが横に適切に仮想デストラクタを書く作業を必要としないため、最も簡単なことのようです。

+1

dllとexeは同じバージョンのC++ランタイムライブラリを使用していますか?彼らは同じコンパイラオプションを使用していますか?はい、はいの場合期待どおりに動作します。 – Niall

答えて

1

DLL間のメモリ管理は本当の苦痛です。

一般に、1つのDLLに割り当てられたメモリは、別のDLLで解放されてはなりません。

明示的な破棄(delete this)関数を提供します。これは、オブジェクトが不要になったときに呼び出さなければならない典型的な解決方法です。

ので(派生クラスで実装されている純粋仮想destroyメソッドを記述)2のために行く:詳細について

class IBase 
{ 
public: 
    virtual void destroy() = 0; 

    // Other pure virtual methods. 
}; 

class Derived : public IBase 
{ 
public: 
    Derived() { m_p = new cSomeClass; } 

    virtual ~Derived() { delete m_p; } 

    virtual void destroy() override { delete this; } 

private: 
    cSomeClass *m_p; 
}; 

extern "C" __declspec(dllexport) IBase * __cdecl createDerived() 
{ 
    return new Derived; 
} 

あなたは(イーライBenderskyのウェブサイトから)GREAT Exporting C++ classes from a DLLを読むことができます。