c++ - 通过引用成员变量返回是否可以接受?

标签 c++ design-patterns reference ownership

假设我有:

class Metadata {
    // stores expensive-to-copy data, provides complex interface to access/modify
}

class SomeObject
public:
    Metadata& GetMetadata() { return mMetadata; }
private:
    Metadata mMetadata;
}

boost::shared_ptr<SomeObject> obj = ...;
obj->GetMetadata().SetTitle("foo");
obj->GetMetadata().GetTitle();

普遍的共识似乎是通过引用返回,尤其是非常量,在除少数特定情况外的所有情况下都非常糟糕。然而,在这种情况下,它似乎是最好的(也是唯一的?)选项:

  1. 我不想退回拷贝,因为我想修改原件(即使它是 r/o,复制也太昂贵了)。
  2. 我不想返回元数据* 或类似的任何东西,因为我不想鼓励存储或传递指针。
  3. 我不想用不相关的元数据包装器调用污染 SomeObject 的接口(interface)。

它引入了一个模糊的要求,即 SomeObject 能够通过引用传回元数据,这意味着必须有一个元数据对象,其生命周期与 SomeObject 的生命周期相同(或长于) - 然而,这是两者之间的确切语义关系对象,并且要求肯定比上述任何选项都好。

我突然想到我可以引入某种不可复制的指针类型并返回它,但这听起来很有趣/似乎有点矫枉过正。我可以让 SomeObject 拥有一个 boost::shared_ptr,但这确实与我所想的语义不太匹配(基本上:如果你现在正在修改,请修改原始 - 如果你稍后阅读/存储,制作拷贝并自己跟踪)。

这里有更好的模式吗?我会不会以某种我没有看到的方式搬起石头砸自己的脚?

最佳答案

返回对将比函数调用更有效的内容的引用是完全可以的。当您返回对类数据成员的左值引用时,只需确保该类实例本身就是一个左值:

struct Foo
{
    X data;

    X & the_data() &   { return data; }
//                ^^^

当您这样做时,如果您的实例是右值,您还可以将数据作为右值返回:

    X && the_data() && { return std::move(data); }
};

关于c++ - 通过引用成员变量返回是否可以接受?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26539226/

相关文章:

c++ - 代表四开棋盘游戏棋子的最佳方式

c++ - 基类集合泛型类型的通信

c++ - 用 C++ 编写递归函数的最佳方法?

python - 由于动态变量,在 Python 中高效地创建列表

c++ - C++错误C2440 : '=' : cannot convert from 'const int' to 'int *' [closed]

dataframe - PySpark DataFrame 列引用 : df. col vs. df ['col' ] vs. F.col ('col')?

Java Observable/Observer 与仅传递引用

c# - 装箱/拆箱,更 retrofit 箱值的引用副本不会反射(reflect)到装箱值

c++ - 如何在 Visual Studio 代码中完成后暂停控制台 C++ 应用程序

c++ - yaml-cpp 在保存时如何重新排序节点?