什么时候需要使用引用?使用引用的好处是什么?


作者:谢之易

链接:https://www.zhihu.com/question/34267829/answer/58414818
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

记忆里《C++ 的设计与演化》一书提过,当初加入“引用”这个语言特性的契机是运算符重载。为了让运算符重载的语法能够更加接近内建的运算符,需要能够让一个函数返回一个左值,通俗的讲就是要能够对一个函数的返回值赋值。

举个例子,假设你想要设计一个类 IntArray 模仿 int 数组,希望支持下面的语法:
IntArray a;
... ...
a[10] = 9527;  // 你想要的效果

显然你需要为 IntArray 增加一个运算符重载,而运算符重载是一个函数,上面你想要的那一句实际上是一个函数调用:
IntArray a;
... ...
a.operator[](10) = 9527;  // 实际的语义(原来这里有个笔误,谢谢 @连小多 的提醒)

这个时候你就得思量一下 operator[] 的返回值是什么。C 语言里只有两个选择,返回 int 或者返回 int*,前者返回出来的是个拷贝,无法赋值,后者的话需要改成 *(a[10]) = xxx,失了语法方便的本意。为了解决这个两难问题,所以加上了引用这个特性。


=== 历史原因交待完毕的分割线 ===


到了今天,引用除了原始用途之外,实际中最主要的用途是以常量引用来修饰函数的输入参数,比如:
void NormalizeBigString(const string& input, string* output) {
  ... ...
}

这里 input 是个输入参数,在函数内部不会被改变,此时用常量引用就是最合适的:一不会在调用函数的时候拷贝一遍 input,二在函数内部使用方便不需要加 *,三从调用函数的地方看过去,NormalizeBigString(string_a, &string_b),单凭语法就能清楚的区分输入和输出参数,可读性更好。

此外,引用常见的用法还有返回内部对象的常量引用:
struct MachineConfig { ... /* 许多许多的配置选项 */ ... }
class FancyMachine {
private:
  Config config_;  // 这台机器的配置选项信息
  ... ...
public:
  // 一能让外界访问配置,二能避免拷贝,三能避免不受控制的配置变化
  const Config& config() { return config_; }
  ... ...
};

你可能感兴趣的:(什么时候需要使用引用?使用引用的好处是什么?)