我正在阅读“Using shared_ptr in dll-interfaces”。在那篇文章中,phlipsy提出了一种方法,在他的答案结束时,不跨DLL边界传递任何特定于实现的对象。基本上,我们的想法是从DLL返回一个原始指针,并在EXE中用原始指针初始化shared_ptr
。
我不认为这是正确的。让我为了简单而重新定型。
// wrong version??
// DLL
Object* createObject()
{
return new Object;
}
// EXE
std::tr1::shared_ptr<Object> p(createObject());
..
当object
被释放时,shared_ptr
使用的销毁上下文/堆与构造期间DLL中使用的不同。
使用shared_ptr
的正确方法是资源分配应与shared_ptr
的初始化位于同一行,以便分配和释放可以使用相同的堆,如下所示。
// right version
// DLL
std::tr1::shared_ptr<Object> createObject()
{
return std::tr1::shared_ptr<Object>(new Object);
}
// EXE
std::tr1::shared_ptr<Object> p(createObject());
..
我是对的吗?
答案 0 :(得分:6)
你同意这两个陈述。第二种正确的方法是通过createObject(..)返回原始指针,用它初始化shared_ptr并将自定义删除器传递给shared_ptr。自定义删除器是一个库函数,如releaseObject(..)。
编辑: 使用您的版本(createObject(..)返回shared_ptr&lt; ..&gt;),您将绑定到库和库用户的特定shared_ptr实现。以我提出的方式,这种限制已经消失。
答案 1 :(得分:1)
一般规则是分配/取消分配内存应始终从同一模块完成。因此,您可以使用分配器创建共享指针,该分配器在分配模块中调用正确的释放方法。
适用于原始指针的规则仍然适用,即使您已将它们包装在智能指针中。