2016-03-24 61 views
1

在我的情況下,我有一個基類的DLL。該DLL可以加載插件。每個插件DLL都會導出一個返回派生對象的create函數。我寧願如果插件DLL中的對象可以刪除自己。如何正確刪除從另一個DLL收到的派生對象?

在下面,我寫下了兩種方法。請忽略丟失的公開/私人陳述。第一種方法當然更簡單,因爲我只需要像平常一樣調用delete,但我不確定它是否有效。第二種方法是明確delete this,因爲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 0123知道對象類型,並且會因爲虛擬析構函數而正確刪除它。
  2. 編寫一個在派生類中實現的純虛擬銷燬方法。
  3. 在創建方法旁邊輸出destroy()方法,該方法使用Base指針並在delete之前執行動態投射。 (因爲我覺得沒有吸引力我沒有寫一個例子這種情況。)

第一種方法似乎是最簡單的,因爲它不要求旁的正常工作寫虛析構函數。

+1

dll和exe是否使用相同版本的C++運行時庫?他們是否使用相同的編譯器選項?如果是,並且是;那麼它將按預期工作。 – Niall

回答

1

DLL之間的內存管理是一個真正的痛苦。

一般情況下,一個DLL中分配的內存不得在另一箇中釋放。

提供一個明確的銷燬(delete this)函數,當不再需要該對象時必須調用該函數,這是典型的解決方案。

,所以還是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; 
} 

進一步的細節可以看大Exporting C++ classes from a DLL(從禮Bendersky的網站)。

相關問題