题
我正在编写一个库和一个演示项目。该项目并不关心我使用哪个版本的库(我可以使用 sdl、directx 或任何我喜欢的东西作为 gfx 后端)。为了得到我做的对象
Obj *obj = libname_newDevice();
现在,我应该使用删除还是应该这样做 obj->deleteMe();
?我问是因为我没有完全执行新操作,所以我不应该执行删除操作?
我有 obj->create(theType);
它返回一个具有 Obj 接口的类。我真正的问题是我需要一个 libname_deleteDevice();
或者是 obj->deleteMe()
好吧,因为我在界面中有一个deleteMe?
解决方案
我会更进一步。
如果使用工厂函数进行创建,则使用工厂函数进行销毁可能是合乎逻辑的。除此之外,还要使对象中的所有内容都安全可靠。
class ObjWrap
{
public:
ObjWrap()
:obj(libname_newDevice())
{}
~ObjWrap()
{ libname_deleteDevice(obj);}
private:
ObjWrap(ObjWrap const&); // Dont copy
void operator=(ObjWrap const&); // Dont copy
Obj* obj;
}; // If you want to copy then you need to extra work on ref counting
// This may need some form of smart pointer.
其他提示
由于你在 libname_newDevice()
(我不得不说这不是一个好方法)中抽象创建,你应该使用像 libname_destroyDevice(obj)
正如Martin的评论所暗示的那样,最好将它们放在自定义类的构造函数和析构函数中,您只需要在堆栈上创建,编译器将负责其余的工作。
请尝试澄清您的问题。我完全不清楚。
- 为什么提到图形后端?与问题相关吗?
- 您是在问应该如何设计您的库或者应该如何使用它?
使用对象工厂来创建对象是一个很好的做法。我认为这就是角色 libname_newDevice()
.
库还应该提供一种删除对象的方法(例如 obj->DeleteMe()
或者 libname_Delete(obj)
).
不要依赖 C++ delete
:调用者和库可能是使用不同版本的编译器编译的,这会在内存和资源分配方面执行不同的操作。因此,如果您的库删除它创建的对象,会更安全。
我认为最好的办法是尊重 RAII 并拥有一些参考计数包装对象(您甚至可以将 shared_ptr 与自定义解除分配器一起使用)。
你绝对不想实现Obj :: deleteMe()。它必须做类似的事情:
delete this;
当你还在这里时 - > deleteMe()。按照Jaywalker的建议,让destroy函数将Obj *作为参数。