该函数需要返回一个指向shared_ptrStructA

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 的原因如下:
  • 返回const shared_ptr,因此此函数的调用者不应更改返回的shared_ptr,后者可能指向内部数据结构
  • 通过引用返回,因此我可以避免shared_ptr
  • 引用计数的+/-
  • shared_ptr包含const StructA&,因此调用者无法更改const shared_ptr的内容。如果我是对的,即使shared_ptr是const,除非该数据是const,否则它不能阻止调用者更改指向的数据。


  • 如果我有任何错误,请纠正我的理解
  • 为此功能提供最佳的返回签名。

  • 谢谢

    最佳答案

    这将取决于函数的功能:

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

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

    返回访问指针时,我经常使用const&惯用语。但是最后它会导致非常细微的错误,尤其是在多线程代码中(我很小心,但我仍然被人咬了)。因此,上面peachykeen的评论很明显,对于所有新代码,我都会遵循该惯用法。不仅为了返回您,而且当函数参数为shared_ptr时也请注意。最后,您真的想知道,只要您有一个由shared_ptr指向的对象,就可以拥有它,而不仅仅是引用长死对象的shared_ptr。

    10-07 19:30
    查看更多