8.2

8.2 引用变量

复合类型
功能:为已定义的变量起另一个名称
主要用途:作为函数的形参。函数将使用的是原始数据, 而不是副本

创建引用变量

int rats;
int & rodents = rats;
& 不是地址运算符, 而是类型标识符的一部分。
必须在引用声明时将其初始化
一旦初始化, 引用将无法改变
int * const pr = &rats; // 引用相当于

将引用作为函数参数

称为按引用传递。

引用的属性和特别

double a;
const double &ra = a;
!!可以通过修改ra的值改变const变量的值!!
按引用传递参数时, 传递的参数必须是一个变量名
refcube(double & ra);
refcube(x + 3.0); // 是错误的
仅当参数为const 引用时, 如果实参与引用参数不匹配, C++将生成临时变量
refcube(const double & ra);
refcube(x + 3.0); // 将生成临时变量
生成临时变量的情况:
1.实参的类型正确, 但不是左值
2.实参的类型不正确, 但可以转换为正确的类型
相当于按值传递, 否则将生成正确的匿名变量
尽可能使用const

C++11 右值引用:

double && rred = 20.0 * 15.0;

将引用用于结构

返回引用, 和返回被引用的类型不同
返回引用:不产生返回值的副本, 返回的是引用指向的变量本身
不要返回局部变量的引用
返回new申请的空间时
int & accumulate();
可以将返回值赋值给新的引用变量
可以将返回值赋值给其他的变量
可以直接使用返回值
accumulate() = four; // 将four的值拷贝到引用变量中, 不是更改引用变量的引用

返回引用的原因

传统返回机制和按值传递函数参数类似:将返回值复制到一个临时位置, 然后程序调用使用这个值。
double m = sqrt(16.0);
cout << sqrt(25.0);
两条语句中, 都是将返回值复制到一个临时位置中, 再将值拷贝到m中, 将值传递给cout
dup = accumulate();
相当于直接把返回的引用指向的变量复制给dup, 没有临时变量, 效率更高。

返回引用注意的问题

避免返回函数终止时不再存在的内存单元的引用
注意返回new申请的空间时, 要将返回值赋值给实际的变量, 否则可能导致内存泄漏

将const用于引用返回类型的原因

将返回值标记为const引用将无法修改返回值的内容
accumulate() = four; // 只是禁用了直接使用返回值更改的情况

将引用用于类对象

传递类对象给函数, C++常用引用。

对象、继承和引用

继承:第13章
ostream是基类, ofstream是派生类
派生类继承了基类的方法, ofstream可以使用ostream的特性
继承的另一个特征
基类可以指向派生类对象, 无需强制类型转换
ostream.setf(ios_base::fixed); // 设置对象置于使用顶点表示法的模式, 返回调用它之前的所有格式化设置, 类型ios_base::fmtflags, 可以保存设置,再设置回来
ostream.setf(ios_base::showpoint); // 设置对象置于显示小数点的模式
ostream.precision(); // 指定显示多少位的小数
ostream.width(); // 设置下一次输出操作使用的字段宽度, 只在显示下一个值时才有效, 然后恢复到默认设置, 默认的字段宽度为0, 表示正好能容纳要显示的内容。
第17章

何时使用引用参数

修改调用函数中的数据对象
提高运行速度

不修改参数时

数据小,值传递
数组, 使用指针
较大的结构, 使用const指针或const引用, 提高效率
类对象, 使用const引用

修改调用函数中数据的函数

内置数据类型, 使用指针
数组, 指针
结构, 引用或指针
类对象, 引用