为啥要返回对小类成员的 const 引用?

Posted

技术标签:

【中文标题】为啥要返回对小类成员的 const 引用?【英文标题】:Why return a const reference to small class members?为什么要返回对小类成员的 const 引用? 【发布时间】:2018-05-02 14:35:09 【问题描述】:

我觉得这个问题肯定是在某个地方,但要么我找不到正确的搜索词,要么不知何故错过了。

假设我有一个像这样保护其成员的类......

class MyClass 
   int m_value;
public:
   MyClass(int v) : m_value(v) 
   int value() const  return m_value; 

我在整个 SO 中都看到了示例代码,它返回一个对成员变量的 const 引用,就像这样......

class MyClass 
   int m_value;
public:
   MyClass(int v) : m_value(v) 
   const int& value() const  return m_value; 
// ^^^^^^^^^^

我了解一般返回 const 的值,以及返回复合对象的引用的值,但是对于小于体系结构指针大小的对象的值是多少?它似乎既效率低又不安全,没有我能想到的优势。


我想在我的示例中可以对构造函数进行类似的讨论,但这个问题集中在此处的返回值上。

This is the SO answer 促使我提出这个问题。

【问题讨论】:

也许,在一个更完整的例子中,用户期望一个引用,因为被引用的值预计会改变,并且用户希望引用总是知道当前值但不能允许更改该值, 别那样做,就这样 @FrançoisAndrieux 我没有想到这一点,有趣的是,您所描述的潜在功能在相关(ish)问题的this answer 中被描述为“不安全”责任。 @Phlucious 这句话几乎适用于任何语言的任何特性;) @Phlucious 如果您不指望它,我可能会成为负担。这仅取决于您要做什么。为工作使用错误的工具总是要付出代价的。 【参考方案1】:

为什么要返回对小类成员的 const 引用?

取决于您是否希望调用者能够绑定对 m_value 的引用。

MyClass myObj;
int const& keep_an_eye_on_you = myObj.value();
cout << "Was: " << keep_an_eye_on_you << endl;
myObj.doSomething(); // say this changes the value held in m_value
cout << "Now: " << keep_an_eye_on_you << endl;

如果 m_value 实际上是不可变的,那么它就没有关系(除了其他人表达的性能问题)。

如果 m_value 可以随时间变化,那么调用者的绑定将反映当前状态,如上例所示。

【讨论】:

【参考方案2】:

const &amp; 返回到int 之类的类型可能完全没有意义,并且可能会降低性能。将const int&amp; 作为函数参数类型传递也可以这样说,但这更容易接受,因为它确实会在调用站点阻止不需要的类型转换。

这只是程序员自己养成的一个坏习惯。

【讨论】:

【参考方案3】:

如果您只谈论int,那么是的,这可能毫无意义。但是当您知道返回或参数类型可以稍后更改并且您使用别名时,输入const &amp; 会很有用,所以稍后您所要做的就是更改您的别名值,它可以超过 8 个字节。像这样

class MyClass 
   using TInnerType = int;
   TInnerType m_value;
public:
   MyClass(const TInnerType& v) : m_value(v) 
   const TInnerType& value() const  return m_value; 
// ^^^^^^^^^^

【讨论】:

确实如此,但是通过一些元编程,您仍然可以让int case 按值返回,而更复杂的类则通过 const ref 返回。 @Bathsheba 是的,但为什么?)如果在您的应用程序中传递 4 和 8 个字节之间没有真正的性能差异(这是常见的情况,您知道),为什么要复杂化您的代码?跨度> +1。有效的场景但过于复杂(恕我直言)除非MyClass 是一个模板并且value() 返回模板参数。

以上是关于为啥要返回对小类成员的 const 引用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在向量类中实现 operator= 时返回 const 引用

为啥即使对于“写入时复制”的 const 成员函数也返回代理类?

在 const 成员函数中返回 C++ 引用

测试页面

为啥在特殊成员函数中将 r 值绑定到 const 左值引用是非法的?

C++,成员函数返回对包含指向 const 对象的指针的向量的 const 引用