C++引用
C++中引用变量是一个别名,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
C++ 引用 vs 指针
引用很容易与指针混淆,它们之间有三个主要的不同:
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象,有点类似指针常量。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。
int a = 10;
int &b = a;//引用,此时a,b操纵同一块地址。
b = 20;//a = 20
引用作函数参数
通过引用,可以让形参修饰实参,简化地址传递。
void myswap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;//使用别名操作数据和使用原名操作数据是一样的,所以这就可以通过引用使形参修饰实参。
}
int main()
{
int a = 10;
int b = 20;
myswap(a,b);
//交换后a = 20,b = 10;
}
第一次看的时候我觉得很奇怪,不是说引用必须要在创建的时候就初始化指向一个对象吗?这里好像没有看见初数化的过程。
其实在main函数里调用myswap,当我们给myswap传入a、b参数时,就已经将myswap中的int &a和int &b分别初始化为a、b了,只不过这里的引用别名和变量名是相同的。
引用作函数的返回值
- 不要返回局部变量的引用。
- 函数的调用可以作为左值。
int &test()//返回了一个引用
{
int a = 10;//局部变量存放在栈区,函数执行完自动释放。
return a;
}
int main()
{
int &b = test();//引用接收返回值,相当于b就是a的别名。
cout << b << endl;//第一次结果正确,10。
cout << b << endl;//第二次结果错误,因为a的地址被释放了,编译器做了一次保留。
}
引用的本质
int a = 10;
int &b = a;//自动转换为 int *const b = &a ,这也是为什么引用的地址不可改,但是数据可改。
b = 20;//内部发现 b 是引用,自动帮我们转换为:*b = 20;
常量引用
- 用来修饰形参,并防止误操作。
int a = 10;
int &b = 10;//错误的,10在内存区里是常量区,引用只能指向栈区或堆区。
const int &b = 10;//正确,加上const后编译器会在内部修改代码:
//int temp = 10; const int &b = temp;所以常量引用可以直接指向常量。