在看Clang源码的过程中遇到过,返回const引用,于是就去google 了一下返回值以及参数传递等相关的知识。
首先,为什么要(const 引用)的返回值?
首先&的引用作用是C++独有的特性。其作用相当于传入参数时不经过拷贝,而是实实在在的传入。
fun(int &a)。如果在函数内部修改了a的值,那就确实修改了a的值。而一般的参数传入方式都是传入一个参数的副本。函数内部的操作都是作用于副本。
对于返回值,也类似。一般返回值也是返回的拷贝值。所以如果将函数内的局部变量以引用方式返回是没有意义的。因为退出函数后,函数内部的局部变量已经被系统回收,所以这样引用方式传出的变量也是无效的。但是一般方式返回的变量反而是有效的。因为一般方式返回的是拷贝值,即使原版已经被销毁也无所谓。
但是,有种情况是个例外。那就是对于生命周期足够长的变量,引用返回就是有效的。比如LZ例子里的int& fun(int &a){return a;},这里的a因为是引用方式传入,所以他的生命周期是大于函数本身的。所以引用方式传出也没有问题。当然其实这个例子一般不常见。真正常见的是下面的例子:
class A
{
public:
A():m_data(0){}
int m_data;
int &get() {return m_data;}
}
这里的m_data的生命周期和类A实例化后的变量一样长,所以显然是长于函数get的。所以引用返回是有效的。而且类似引用传入,少了拷贝的步骤,效率更高。当然本例中int本身不复杂,效率没啥区别。但若是一个相当复杂的结构体,那效率差别就大了。
当然引用返回最大的作用就在下面:
A a;
a.get(a) += 1; //这样是合法的。这就是引用返回的最大作用。可以对返回值直接做这样的操作。专业点的话就是,可以直接当作左值。这可是相当有用的。
下面可以来个更具体的例子:
struct B
{
B();
int m_data[10];
int& operator [] (int i){return m_data[i];}
}
void main()
{
B b;
b[0] = 1;
b[1] = 2; //怎么样,爽吧。
}
当然 若返回类型变为const &,就失去了左值的作用。但是省去拷贝,增加效率的作用还是在的