本文梳理了个人对于C++引用及函数参数传递的一些思考,如有纰漏,欢迎指正。
若函数返回类型是引用,则该引用绑定return后面的左值表达式(一般是变量);若函数返回类型非引用,则该返回类型是函数调用点创建的临时对象的类型,用return后面的语句来拷贝初始化它。可见,
1. 由于引用不是对象,所以当返回类型是引用时,无需创建临时对象,节省了内存。
2. 同时,显然我们不能返回函数中定义的局部变量的引用,因为它在函数结束后就被释放了。
3. 概括来讲,使用引用的目的就是避免拷贝操作,C++ 11新引入的右值引用的概念也是为了这个目的。
设想一种应用场景是某函数返回值作为另一个函数的一个实参,并且该函数返回类型是普通类型,所以调用点创建了一个临时对象,接受函数返回值的拷贝。但作为另一个函数的实参,我们不希望该临时对象再以拷贝的方式初始化形参,那么可以将形参定义为const T&类型,接受该临时对象(临时对象一定是右值),但局限性在于该函数自此无法修改T的值;所以更灵活的方案是将形参定义为T&&类型,同样接受该临时对象,但无const限制。该临时对象的内存由于被右值引用,所以不会被释放。以上形参定义为T&&会带来另一个问题:若实参不是临时对象,是一个左值怎么办?由于T&&不接受左值,所以当我们确信该左值之后不在其他地方使用的前提下,可以使用move(lvalue)将它转化为右值。
引用类型必须与它所绑定的对象类型一致,但有两个例外:
1. const引用在初始化时可以绑定任何可转化类型的对象(包括字面值常量);
2. 基类引用(或指针)可以绑定派生类对象,动态绑定涵义在于运行时调用哪个类定义的虚函数版本在编译时是未知的。