正确使用shared_ptr来消除DLL边界的重新分配

时间:2011-10-16 16:16:12

标签: c++ shared-ptr

我正在阅读“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());
..

我是对的吗?

2 个答案:

答案 0 :(得分:6)

你同意这两个陈述。第二种正确的方法是通过createObject(..)返回原始指针,用它初始化shared_ptr并将自定义删除器传递给shared_ptr。自定义删除器是一个库函数,如releaseObject(..)。

编辑: 使用您的版本(createObject(..)返回shared_ptr&lt; ..&gt;),您将绑定到库和库用户的特定shared_ptr实现。以我提出的方式,这种限制已经消失。

答案 1 :(得分:1)

一般规则是分配/取消分配内存应始终从同一模块完成。因此,您可以使用分配器创建共享指针,该分配器在分配模块中调用正确的释放方法。

适用于原始指针的规则仍然适用,即使您已将它们包装在智能指针中。