1

该函数需要返回一个shared_ptr指向StructA.

struct StructA
{
    // complicated struct that also holds other sub-structure
    ....
};

const boost::shared_ptr<const StructA&>& GetStructA(...)
{...} #0.5

const boost::shared_ptr<const StructA>& GetStructA(...)
{...} #0

const boost::shared_ptr<StructA>& GetStructA(...)
{...} #1

const boost::shared_ptr<StructA> GetStructA(...)
{...} #2

boost::shared_ptr<const StructA> 
{...} #3

boost::shared_ptr<StructA> GetStructA(...)
{...} #4

boost::shared_ptr<StructA>& GetStructA(...)
{...} #5

boost::shared_ptr<StructA&> GetStructA(...)
{...} #6

有很多选择,我相信其中一个是最好的(如果还有人请指出)。

就个人而言,我更喜欢使用#0

const boost::shared_ptr<const StructA&>& GetStructA(...)
{...} #0

遗留系统使用#2

const boost::shared_ptr<StructA>  GetStructA(...)
{...} #2

我更喜欢选择#0的原因如下:

  1. return const shared_ptr,因此该函数的调用者不应更改返回的 shared_ptr 可能指向内部数据结构

  2. 通过引用返回,这样我就可以避免 +/- 的 shared_ptr 的引用计数

  3. shared_ptr 持有 const StructA&,因此调用者无法更改 const shared_ptr 的内容。如果我是对的,即使 shared_ptr 是 const,它也不能阻止调用者更改指向的数据,除非数据是 const。

  1. 如果我犯了任何错误,请纠正我的理解
  2. 为此函数提供最佳返回签名。

谢谢

4

1 回答 1

2

这取决于函数的作用:

  • 它是在创建 StructA 的新对象吗?如果是,那么您必须返回 shared_ptr 的副本。
  • 它只是提供对您知道在返回的引用下不会过期的 StructA 对象的访问吗?然后你可以返回 const& (但不要 - 见下文)

正如您自己所怀疑的那样, shared_ptr 上的 const& 不会阻止对它指向的对象的非 const 访问 - 它只是意味着 shared_ptr 对象本身是常量并且不能被重置或指向其他对象。在这种情况下,shared_ptr 的语义与普通指针的语义相同。

在返回访问指针时,我曾经经常使用 const& 习惯用法。但最终它会导致非常微妙的错误,尤其是在多线程代码中(我很小心,但我还是被咬了)。所以上面 peachykeen 的评论是正确的,我对所有新代码都遵循这个成语。不仅要注意返回,还要注意函数参数是 shared_ptr 时。最后,您真的想知道,每当您有一个由 shared_ptr 指向的对象时-您确实拥有它,而不仅仅是对一个长期死对象的 shared_ptr 的引用。

于 2012-07-25T15:43:48.423 回答