C++ 引用小结
从之前的博客中有提到,C++有两种特性
return by value and return by reference
一种是返回值,一种是返回引用
并且,在一般情况下,传引用比传值效率更高。
先说说引用是什么,引用用的是&符号,&符号既可以用来当引用,也可以用来当取地址符,只不过使用方法不同。
引用的本质是别名。
引用的基本使用方法是
int b = 1; int & a = b;
此时a就是b的引用,也就是b的别名,那可能会发现一个问题,我为什么不直接用b,而去特意创建一个别名去使用b呢。
这里去思考一下typedef的作用就知道了。
我们可以用它来接收返回值,并且创建引用
inline complex& __doaml (complex* ths, const complex& r) { double f = ths->re * r.re - ths->im * r.im; ths->im = ths->re * r.im + ths->im * r.re; ths->re = f; return *ths; }
传递者是*ths,是一个“实体”,而接收者是 complex& , 也就是一个引用,其实这里也可以直接接收值,但如果之后还要使用*ths,这里的用引用接收之后使用,效率会快上很多。
(可以把这整个函数想象成返回了一个 *ths 的引用)
引用和指针是差不多的,因为
T& ... = T* const ... 指针无法改变
const T& ... = const T* const ... 指针无法改变,指针指向的值也无法改变
所以引用就是一个不能改变指向的指针,传递的也是地址。
并且引用能够解决 派生类切割问题。
比如说有两个类
class person { public: string name; int age; }; class student: public person { public: string classid;//班级名 }; ... void printattribute(person p) { cout << p.name; cout << p.classid; } ... //假设 student s; printattribute(s);
当派生类对象s 传入到 printattribute()里去后,会切割掉自己原本有的属性,变成一个原原本本的基类,此时将没有classid这个属性。
如果传的是引用,则可以解决这个问题。
void printattribute(const person& p) { cout << p.name; cout << p.classid; }
这样 p 的行为就和传入到函数的真实类型一致了。