C++函数中的按引用调用与返回

Edit

在C++中提供了按引用调用的方式,如下

class A{}
A& func(A& a)
{
A* b = new A();
b->param = a.param;
return *b;
}

引用既可以作为参数传递,也可以是返回值。所有的书上都提到引用即可视为对象的别名。他有如下特性:

  1. 可以像对象一样操作引用,使用"."操作符,而无需"->"操作符
  2. 其地址与引用的对象一致
  3. 所谓别名,就是引用已经与对象绑定,以下代码最后一行是不允许的。
A a;
A b;
A& c = a;
c = b;
  1. 引用是C++中的语法糖,其存在的目的就是让传递对象的时候更廉价一些,尽量避免调用构造函数。

作为参数

其实C++中不按引用传递自定义类对象参数也是可以的。如下:

class A{}
void func (A a);
void func (A& a);

两者均可以,区别在

  1. 前者传递时要分配一个临时变量,并调用A的拷贝构造函数。
  2. 前者在函数体内,对a的修改不会影响到外部a对象。这往往是我们想要的。所以,按引用调用的时候,往往更好的写法是:
void func (const A& a); // 用const来保证a对象不被修改

作为返回值

在定义运算符重载的时候,我们往往使用return *this;来保证链式调用,例如:

class A {
A& operator=(A& param){
...
return *this;
};
}
A a, b, c;
a = b = c;

如果不按引用返回,可以吗?

class A {
A operator=(A& param){
...
return *this;
};
}
A a, b, c;
a = b = c;

答案是也是可以的。区别是:

  • 不按引用传递时,b=c的操作返回时会先分配一个临时变量,以*this为参数调用A的拷贝构造函数,然后再调用一次A的拷贝构造函数将该临时变量作为结果传递给a=操作符函数。
  • 按引用传递,同样b=c返回时会分配一个临时变量,并调用A的拷贝构造函数,然后将该临时变量的引用值传给a=操作符函数。

可见虽然两者都能做到链式操作,但是按引用返回少调用了一次拷贝构造函数,效率提升。这与引用存在的价值也是一致的。

%23%20C++%u51FD%u6570%u4E2D%u7684%u6309%u5F15%u7528%u8C03%u7528%u4E0E%u8FD4%u56DE%0A@%28myblog%29%5Bc/c++%5D%0A%0A%u5728C++%u4E2D%u63D0%u4F9B%u4E86%u6309%u5F15%u7528%u8C03%u7528%u7684%u65B9%u5F0F%uFF0C%u5982%u4E0B%0A%60%60%60%0Aclass%20A%7B%7D%0AA%26%20func%28A%26%20a%29%0A%7B%0A%09A*%20b%20%3D%20new%20A%28%29%3B%0A%09b-%3Eparam%20%3D%20a.param%3B%0A%09return%20*b%3B%0A%7D%0A%60%60%60%0A%u5F15%u7528%u65E2%u53EF%u4EE5%u4F5C%u4E3A%u53C2%u6570%u4F20%u9012%uFF0C%u4E5F%u53EF%u4EE5%u662F%u8FD4%u56DE%u503C%u3002%u6240%u6709%u7684%u4E66%u4E0A%u90FD%u63D0%u5230%u5F15%u7528%u5373%u53EF%u89C6%u4E3A%u5BF9%u8C61%u7684%u522B%u540D%u3002%u4ED6%u6709%u5982%u4E0B%u7279%u6027%uFF1A%0A1.%20%u53EF%u4EE5%u50CF%u5BF9%u8C61%u4E00%u6837%u64CD%u4F5C%u5F15%u7528%uFF0C%u4F7F%u7528%60%22.%22%60%u64CD%u4F5C%u7B26%uFF0C%u800C%u65E0%u9700%60%22-%3E%22%60%u64CD%u4F5C%u7B26%0A2.%20%u5176%u5730%u5740%u4E0E%u5F15%u7528%u7684%u5BF9%u8C61%u4E00%u81F4%0A3.%20%u6240%u8C13%u522B%u540D%uFF0C%u5C31%u662F%u5F15%u7528%u5DF2%u7ECF%u4E0E%u5BF9%u8C61%u7ED1%u5B9A%uFF0C%u4EE5%u4E0B%u4EE3%u7801%u6700%u540E%u4E00%u884C%u662F%u4E0D%u5141%u8BB8%u7684%u3002%0A%60%60%60%0AA%20a%3B%0AA%20b%3B%0AA%26%20c%20%3D%20a%3B%0Ac%20%3D%20b%3B%0A%60%60%60%0A4.%20%u5F15%u7528%u662FC++%u4E2D%u7684%u8BED%u6CD5%u7CD6%uFF0C%u5176%u5B58%u5728%u7684%u76EE%u7684%u5C31%u662F%u8BA9%u4F20%u9012%u5BF9%u8C61%u7684%u65F6%u5019%u66F4%u5EC9%u4EF7%u4E00%u4E9B%uFF0C%u5C3D%u91CF%u907F%u514D%u8C03%u7528%u6784%u9020%u51FD%u6570%u3002%0A%0A%23%23%20%u4F5C%u4E3A%u53C2%u6570%0A%u5176%u5B9EC++%u4E2D%u4E0D%u6309%u5F15%u7528%u4F20%u9012%u81EA%u5B9A%u4E49%u7C7B%u5BF9%u8C61%u53C2%u6570%u4E5F%u662F%u53EF%u4EE5%u7684%u3002%u5982%u4E0B%uFF1A%0A%60%60%60%0Aclass%20A%7B%7D%0Avoid%20func%20%28A%20a%29%3B%0Avoid%20func%20%28A%26%20a%29%3B%0A%60%60%60%0A%u4E24%u8005%u5747%u53EF%u4EE5%uFF0C%u533A%u522B%u5728%0A1.%20%u524D%u8005%u4F20%u9012%u65F6%u8981%u5206%u914D%u4E00%u4E2A%u4E34%u65F6%u53D8%u91CF%uFF0C%u5E76%u8C03%u7528%60A%60%u7684%u62F7%u8D1D%u6784%u9020%u51FD%u6570%u3002%0A2.%20%u524D%u8005%u5728%u51FD%u6570%u4F53%u5185%uFF0C%u5BF9%60a%60%u7684%u4FEE%u6539%u4E0D%u4F1A%u5F71%u54CD%u5230%u5916%u90E8%60a%60%u5BF9%u8C61%u3002%u8FD9%u5F80%u5F80%u662F%u6211%u4EEC%u60F3%u8981%u7684%u3002%u6240%u4EE5%uFF0C%u6309%u5F15%u7528%u8C03%u7528%u7684%u65F6%u5019%uFF0C%u5F80%u5F80%u66F4%u597D%u7684%u5199%u6CD5%u662F%uFF1A%0A%60%60%60%0Avoid%20func%20%28const%20A%26%20a%29%3B%20//%20%u7528const%u6765%u4FDD%u8BC1a%u5BF9%u8C61%u4E0D%u88AB%u4FEE%u6539%0A%60%60%60%0A%0A%23%23%20%u4F5C%u4E3A%u8FD4%u56DE%u503C%0A%u5728%u5B9A%u4E49%u8FD0%u7B97%u7B26%u91CD%u8F7D%u7684%u65F6%u5019%uFF0C%u6211%u4EEC%u5F80%u5F80%u4F7F%u7528%60return%20*this%3B%60%u6765%u4FDD%u8BC1%u94FE%u5F0F%u8C03%u7528%uFF0C%u4F8B%u5982%uFF1A%0A%60%60%60%0Aclass%20A%20%7B%0A%09A%26%20operator%3D%28A%26%20param%29%7B%0A%09%09...%0A%09%09return%20*this%3B%0A%09%7D%3B%0A%7D%0AA%20a%2C%20b%2C%20c%3B%0Aa%20%3D%20b%20%3D%20c%3B%0A%60%60%60%0A%u5982%u679C%u4E0D%u6309%u5F15%u7528%u8FD4%u56DE%uFF0C%u53EF%u4EE5%u5417%uFF1F%0A%60%60%60%0Aclass%20A%20%7B%0A%09A%20operator%3D%28A%26%20param%29%7B%0A%09%09...%0A%09%09return%20*this%3B%0A%09%7D%3B%0A%7D%0AA%20a%2C%20b%2C%20c%3B%0Aa%20%3D%20b%20%3D%20c%3B%0A%60%60%60%0A%u7B54%u6848%u662F%u4E5F%u662F%u53EF%u4EE5%u7684%u3002%u533A%u522B%u662F%uFF1A%0A-%20%u4E0D%u6309%u5F15%u7528%u4F20%u9012%u65F6%uFF0C%60b%3Dc%60%u7684%u64CD%u4F5C%u8FD4%u56DE%u65F6%u4F1A%u5148%u5206%u914D%u4E00%u4E2A%u4E34%u65F6%u53D8%u91CF%uFF0C%u4EE5%60*this%60%u4E3A%u53C2%u6570%u8C03%u7528%60A%60%u7684%u62F7%u8D1D%u6784%u9020%u51FD%u6570%uFF0C%u7136%u540E%u518D%u8C03%u7528%u4E00%u6B21%60A%60%u7684%u62F7%u8D1D%u6784%u9020%u51FD%u6570%u5C06%u8BE5%u4E34%u65F6%u53D8%u91CF%u4F5C%u4E3A%u7ED3%u679C%u4F20%u9012%u7ED9%60a%60%u7684%60%3D%60%u64CD%u4F5C%u7B26%u51FD%u6570%u3002%0A-%20%u6309%u5F15%u7528%u4F20%u9012%uFF0C%u540C%u6837%60b%3Dc%60%u8FD4%u56DE%u65F6%u4F1A%u5206%u914D%u4E00%u4E2A%u4E34%u65F6%u53D8%u91CF%uFF0C%u5E76%u8C03%u7528%60A%60%u7684%u62F7%u8D1D%u6784%u9020%u51FD%u6570%uFF0C%u7136%u540E%u5C06%u8BE5%u4E34%u65F6%u53D8%u91CF%u7684%u5F15%u7528%u503C%u4F20%u7ED9%60a%60%u7684%60%3D%60%u64CD%u4F5C%u7B26%u51FD%u6570%u3002%0A%0A%u53EF%u89C1%u867D%u7136%u4E24%u8005%u90FD%u80FD%u505A%u5230%u94FE%u5F0F%u64CD%u4F5C%uFF0C%u4F46%u662F%u6309%u5F15%u7528%u8FD4%u56DE%u5C11%u8C03%u7528%u4E86%u4E00%u6B21%u62F7%u8D1D%u6784%u9020%u51FD%u6570%uFF0C%u6548%u7387%u63D0%u5347%u3002%u8FD9%u4E0E%u5F15%u7528%u5B58%u5728%u7684%u4EF7%u503C%u4E5F%u662F%u4E00%u81F4%u7684%u3002%0A%0A