C++ 如何正确删除从另一个DLL接收的派生对象?

C++ 如何正确删除从另一个DLL接收的派生对象?,c++,dll,delete-operator,virtual-destructor,C++,Dll,Delete Operator,Virtual Destructor,在我的场景中,我有一个带有基类的DLL。这个DLL可以加载插件。每个插件DLL导出一个create函数,该函数返回一个派生对象。我更喜欢插件DLL中的对象是否可以删除它们自己 在下面,我写下了两种方法。请忽略缺少的公共/私人声明。第一种方法当然更简单,因为我只需要像往常一样调用delete,但我不确定它是否有效。第二种方法是显式的删除此,因为此必须具有派生类型,对吗 // main DLL class Base1 { virtual ~Base(){} }; class Base2

在我的场景中,我有一个带有基类的DLL。这个DLL可以加载插件。每个插件DLL导出一个create函数,该函数返回一个派生对象。我更喜欢插件DLL中的对象是否可以删除它们自己

在下面,我写下了两种方法。请忽略缺少的公共/私人声明。第一种方法当然更简单,因为我只需要像往常一样调用delete,但我不确定它是否有效。第二种方法是显式的
删除此
,因为
必须具有派生类型,对吗

// 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?

}
哪一个是“正确的”,即使用基类指针正确删除派生对象

  • delete
    知道对象类型,并会因为虚拟析构函数而正确删除它
  • 编写一个在派生类中实现的纯虚拟销毁方法
  • 导出create方法旁边的destroy()方法,该方法采用
    Base
    指针,并在
    delete
    之前执行动态强制转换。(我没有为这个案例写一个例子,因为我觉得它没有吸引力。)

  • 第一种方法似乎是最简单的,因为除了正确编写虚拟析构函数外,它不需要其他工作。

    DLL之间的内存管理是一个真正的难题

    通常,在一个DLL中分配的内存不能在另一个DLL中释放

    典型的解决方案是提供显式销毁(
    delete this
    )函数,当不再需要对象时必须调用该函数

    因此,选择2(编写一个在派生类中实现的纯虚拟销毁方法):


    有关更多详细信息,您可以阅读GREAT(来自Eli Bendersky的网站)。

    无需在子类中单独删除func。更新至manlio帖子:

    //在标题中定义抽象类和函数

    #ifdef _EXPORTING
    #define CLASS_DECLSPEC    __declspec(dllexport)
    #else
    #define CLASS_DECLSPEC    __declspec(dllimport)
    #endif
    class CLASS_DECLSPEC IBase
    {
    public:
      // implement function in parent class
      void destroy(){delete this;};
    
      virtual ~IBase(){};
    
      // Other pure virtual methods.
    };
    
    //导入dll源中的头文件

    class Derived : public IBase
        {
        public:
           Derived() { m_p = new cSomeClass; }
           virtual ~Derived() { delete m_p; }
        private:
           cSomeClass *m_p;
    };
    extern "C" __declspec(dllexport) IBase * __cdecl createDerived()
    {
      return new Derived;
    }
    

    DLL和EXE是否使用C++运行库的相同版本?它们使用相同的编译器选项吗?如果是,是;;然后它就会像预期的那样工作。
    class Derived : public IBase
        {
        public:
           Derived() { m_p = new cSomeClass; }
           virtual ~Derived() { delete m_p; }
        private:
           cSomeClass *m_p;
    };
    extern "C" __declspec(dllexport) IBase * __cdecl createDerived()
    {
      return new Derived;
    }