gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 02:17:03 24 4
gpt4 key购买 nike

在我的场景中,我有一个带有基类的 DLL。这个 DLL 可以加载插件。每个插件 DLL 导出一个返回派生对象的创建函数。我希望插件 DLL 中的对象可以自行删除。

下面我分别记下了两种方式。请忽略缺失的公共(public)/私有(private)声明。第一种方式当然更简单,因为我只需要像往常一样调用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 知道对象类型并将由于虚拟析构函数而正确删除它。
  2. 编写一个在派生类中实现的纯虚拟销毁方法。
  3. 在创建方法旁边导出 destroy() 方法,该方法采用 Base 指针并在 delete 之前进行动态转换。 (我没有为这个案例写一个例子,因为我觉得它没有吸引力。)

第一种方法似乎是最简单的,因为它不需要正确编写虚拟析构函数。

最佳答案

DLL 之间的内存管理是一个真正的痛苦。

一般来说,在一个 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;
}

有关更多详细信息,您可以阅读 GREAT Exporting C++ classes from a DLL (来自 Eli Bendersky 的网站)。

关于c++ - 如何正确删除从另一个 DLL 接收到的派生对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36199347/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com