返回智能指针时的最佳做法

Rol*_*lle 31 c++ boost smart-pointers

返回智能指针时的最佳做法是什么,例如boost :: shared_ptr?我应该通过标准返回智能指针,还是底层的原始指针?我来自C#所以我倾向于总是返回智能指针,因为它感觉正确.像这样(跳过const-correctness更短的代码):

class X
{
public:
    boost::shared_ptr<Y> getInternal() {return m_internal;}

private:
    boost::shared_ptr<Y> m_internal;
}
Run Code Online (Sandbox Code Playgroud)

但是我看到一些有经验的编码器返回原始指针,并将原始指针放在向量中.做正确的方法是什么?

Edo*_* A. 23

没有"正确"的方式.这取决于具体情况.

您可以使用智能指针在内部处理内存,并在外部提供引用或原始指针.毕竟,您的界面用户不需要知道如何在内部管理内存.在同步环境中,这是安全有效的.在异步上下文中,存在许多缺陷.

如果您不确定该怎么做,您可以安全地将智能指针返回给您的呼叫者.当引用计数达到零时,将释放该对象.只要确保你没有一个能够永久保存对象智能指针的类,从而防止在需要时重新分配.

最后要注意,在C++中不要过度使用动态分配的对象.在许多情况下,您不需要指针,可以处理引用和const引用.这更安全,减少了内存分配器的压力.

  • @MikeC:返回`unique_ptr`是完全安全的.事实上,返回`unique_ptr &&`几乎总是不安全的. (2认同)

Tod*_*ner 11

这取决于指针的含义.

返回shared_pointer时,您在语法上说"您将共享此对象的所有权",这样,如果原始容器对象在释放指针之前死亡,则该对象仍将存在.

返回一个原始指针说:"你知道这个对象,但不拥有它".这是一种传递控制的方式,但不能将生命保持与原始所有者联系在一起.

(在一些较旧的c程序中,它意味着"现在删除我是你的问题",但我强烈建议避免使用这个程序)

通常,默认为共享可以省去很多麻烦,但这取决于您的设计.


iai*_*ain 8

我按照以下指南将指针参数传递给函数并返回指针:

boost::shared_ptr
Run Code Online (Sandbox Code Playgroud)

API和客户端共享此对象的所有权.但是shared_ptr,如果对象表示某种图形,则必须小心避免使用循环引用.因此,我试图限制我的使用shared_ptr.

boost::weak_ptr / raw pointer
Run Code Online (Sandbox Code Playgroud)

API拥有此对象,您可以在有效时共享它.如果客户端有可能比api更长寿,我会使用weak_ptr.

std::auto_ptr
Run Code Online (Sandbox Code Playgroud)

API正在创建一个对象,但客户端拥有该对象.这可以确保返回的代码是异常安全的,并明确说明正在转移所有权.

boost::scoped_ptr
Run Code Online (Sandbox Code Playgroud)

用于指向存储在堆栈中的对象或作为类成员变量的指针.我先尝试使用scoped_ptr.

像所有指导方针一样,有时规则会发生冲突或不得不弯曲,然后我会尝试使用情报.

  • 我更喜欢boost :: unique_ptr而不是std :: auto_ptr,因为它更难以意外地移动所有权. (3认同)

Joh*_*ell 7

我通常会从工厂或类似的地方返回"拥有"/"独特"的智能指针,以明确谁负责清理.

此示例https://ideone.com/qJnzva显示了std::unique_ptr当调用者分配值的变量范围超出范围时,如何返回将被删除的内容.

虽然智能指针确实删除了自己的指针,但是持有智能指针的变量的生命周期由调用者100%控制,因此调用者决定何时删除指针.但是,由于它是"独特"和"拥有"的智能指针,因此没有其他客户端可以控制生命周期.