请记得那些对你好的人,因为他本可以不这样
——宫崎骏 《千与千寻》
引用
引用是变量的一个别名,而是给一个已经定义的变量重新起一个别名。
定义的格式为:
类型 &引用变量名 = 已定义过的变量名;
引用的特点:
1. 一个变量可取多个别名
2. 引用必须初始化
3. 引用只能在初始化的时候引用一次,不能改变为再引用其他的变量。
void TestReference1 ()
{
int a = 1;
int& b = a;
cout<<"a:address->" <<&a<< endl;
cout<<"b:address->" <<&b<< endl;
a = 2;
b = 3;
int& c = b; // 引用一个引用变量,别名的别名
c = 4;
}
- const引用
void TestReference2 ()
{
int d1 = 4;
const int & d2 = d1;
d1 = 5; // d1改变 d2的值也会改变。
//d2 = 6; // 不能给常量(不能被修改的量)赋值
const int d3 = 1;
const int & d4 = d3;
//int&d5 = d3;
const int & d6 = 5; // 常量具有常性,只有常引用可以引用常量
double d7 = 1.1;
//int& d8 = d7; //d7是double类型,d8是int,d7赋值给 d8时要生成一个临时变量
// 也就是说d8引用的是这个带有常性的临时变量,所以不能赋值。
const int& d9 = d7;
}
引用通常用于函数参数列表和函数返回值。下面列出了 C++ 程序员必须清楚的两个与 C++ 引用相关的重要概念:
概念 | 描述 |
---|---|
把引用作为参数 | C++ 支持把引用作为参数传给函数,这比传一般的参数更安全。 |
把引用作为返回值 | 可以从 C++ 函数中返回引用,就像返回其他数据类型一样。 |
- 引用作为参数
#include <iostream>
using namespace std;
// 函数声明
void swap(int& x, int& y);
int main ()
{
// 局部变量声明
int a = 100;
int b = 200;
cout << "交换前,a 的值:" << a << endl;
cout << "交换前,b 的值:" << b << endl;
/* 调用函数来交换值 */
swap(a, b);
cout << "交换后,a 的值:" << a << endl;
cout << "交换后,b 的值:" << b << endl;
return 0;
}
// 函数定义
void swap(int& x, int& y)
{
int temp;
temp = x; /* 保存地址 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 x 赋值给 y */
return;
}
代码被编译和执行时,产生下列结果:
交换前,a 的值: 100
交换前,b 的值: 200
交换后,a 的值: 200
交换后,b 的值: 100
引用作为函数参数
C++之所以增加引用类型, 主要是把它作为函数参数,以扩充函数传递数据的功能。
C++ 函数传参:
(1)将变量名作为实参和形参。这时传给形参的是变量的值,传递是单向的。如果在执行函数期间形参的值发生变化,并不传回给实参。因为在调用函数时,形参和实参不是同一个存储单元。// 同 c
(2) 传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种通过形参指针可以改变实参的值。// 同 c
(3) C++提供了 传递变量的引用。形参是引用变量,和实参是一个变量,调用函数时,形参(引用变量)指向实参变量单元。这种通过形参引用可以改变实参的值。
- 引用作为返回值
通过使用引用来替代指针,会使 C++ 程序更容易阅读和维护。C++ 函数可以返回一个引用,方式与返回一个指针类似。
当函数返回一个引用时,则返回一个指向返回值的隐式指针
。这样,函数就可以放在赋值语句的左边。例如,请看下面这个简单的程序:
#include <iostream>
using namespace std;
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{
return vals[i]; // 返回第 i 个元素的引用
}
// 要调用上面定义函数的主函数
int main ()
{
cout << "改变前的值" << endl;
for ( int i = 0; i < 5; i++ )
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
setValues(1) = 20.23; // 改变第 2 个元素
setValues(3) = 70.8; // 改变第 4 个元素
cout << "改变后的值" << endl;
for ( int i = 0; i < 5; i++ )
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
return 0;
}
代码被编译和执行时,产生下列结果:
改变前的值
vals[0] = 10.1
vals[1] = 12.6
vals[2] = 33.1
vals[3] = 24.1
vals[4] = 50
改变后的值
vals[0] = 10.1
vals[1] = 20.23
vals[2] = 33.1
vals[3] = 70.8
vals[4] = 50
结论:
1. 不要返回一个临时变量的引用。
2. 如果返回对象出了当前函数的作用域依旧存在,则最好使用引用返回,因为这样更高效。
C++ 引用 vs 指针
引用和指针的区别和联系
- 引用只能在定义时初始化一次,之后不能改变指向其它变量(从一而终);指针变量的值可变。
- 引用必须指向有效的变量,指针可以为空。
- sizeof指针对象和引用对象的意义不一样。sizeof引用得到的是所指向的变量的大小,而sizeof指针是对象地址的大小。
- 指针和引用自增(++)自减(–)意义不一样。
- 相对而言,引用比指针更安全。
总结:
指针比引用更灵活,但是也更危险。使用指针时一定要注意检查指针是否为空。指针所指的地址释放以后最好置0,否则可能存在野指针问题。