C++函数中的按引用调用与返回
在C++中提供了按引用调用的方式,如下
class A{}A& func(A& a){ A* b = new A(); b->param = a.param; return *b;}
引用既可以作为参数传递,也可以是返回值。所有的书上都提到引用即可视为对象的别名。他有如下特性:
- 可以像对象一样操作引用,使用
"."
操作符,而无需"->"
操作符 - 其地址与引用的对象一致
- 所谓别名,就是引用已经与对象绑定,以下代码最后一行是不允许的。
A a;A b;A& c = a;c = b;
- 引用是C++中的语法糖,其存在的目的就是让传递对象的时候更廉价一些,尽量避免调用构造函数。
作为参数
其实C++中不按引用传递自定义类对象参数也是可以的。如下:
class A{}void func (A a);void func (A& a);
两者均可以,区别在
- 前者传递时要分配一个临时变量,并调用
A
的拷贝构造函数。 - 前者在函数体内,对
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
的=
操作符函数。
可见虽然两者都能做到链式操作,但是按引用返回少调用了一次拷贝构造函数,效率提升。这与引用存在的价值也是一致的。