1.引用的意义
- 引用作为变量名存在,在一些场合可以
代替指针
- 引用相对于指针有更好的可读性和实用性
比如下面的swap
函数进行对比
void swap(int& a,int& b)
{
int t = a;
a = b;
b = t;
}
void swap(int* a,int* b)
{
int t = a;
*a = *b;
*b = t;
}
- 需要注意的是:函数中引用形参
不需要对其进行初始化
2. 特殊的引用
2.1 const引用
- 在c++中可以声明
const引用
- const Type& name = var
- const引用让变量具有
只读属性
示例:
int a = 4;
const int& b = a;
int*p = (int*)&b;
b = 5;//error,只读属性
*p = 5;//ok,修改变量a的值
2.2 特殊的引用
- 当使用常量对const引用进行初始化时,C++编译器会为
常量值分配空间
,并且引用名作为这段空间的别名
const int& b = 1;
int*p = (int*)&b;
b = 5;//error,只读属性
*p = 5;//ok,修改变量a的值
结论:使用常量对const引用初始化后将生成一个只读变量
3. 引用是否有存储空间
代码示例:
#include <iostream>
#include <stdio.h>
using namespace std;
struct TRef
{
char* before;
char& now;
char* after;
};
int main()
{
char a = 'a';
char& b = a;
char c = 'c';
TRef r = { &a,b,&c};
cout << "sizeof(r) = " << sizeof(r) << endl;
cout << "sizeof(r.befor) = " <<sizeof(r.before) << endl;
cout << "sizeof(r.now) = " << sizeof(r.now) << endl;
cout << "sizeof(r.after) = " << sizeof(r.after) << endl;
cout << "&r.before = " << &r.before << endl;
cout << "&r.after = " << &r.after << endl;
return 0;
}
结果:
sizeof(r) = 12
sizeof(r.befor) = 4
sizeof(r.now) = 1
sizeof(r.after) = 4
&r.before = 0038FA64
&r.after = 0038FA6C
对应的汇编代码为:
char a = 'a';
003B2602 mov byte ptr [a],61h
char& b = a;
003B2606 lea eax,[a] //将a的地址在eax中,eax=&a
003B2609 mov dword ptr [b],eax//将eax的值赋给b,b=&a
char c = 'c';
003B260C mov byte ptr [c],63h
TRef r = { &a,b,&c};
003B2610 lea eax,[a]
003B2613 mov dword ptr [r],eax
003B2616 mov eax,dword ptr [b]
003B2619 mov dword ptr [ebp-34h],eax
003B261C lea eax,[c]
003B261F mov dword ptr [ebp-30h],eax
4. 引用的本质
- 引用在C++的内部实现一个指针常量,从上面的编程示例也可以看出来
注意:
- 在C++编译器在编译过程中,用
指针常量
作为引用的内 部实现,因此引用所占的内存空间与指针
相同 - 从使用的角度来说,
引用只是一个别名
,C++为了实用性隐藏的引用存储空间这一细节
5. 引用的意义
- C++中的引用多数情况下用来代替指针
- 功能性:可以满足多数需要使用指针的场合
- 安全性:可以避开由于使用指针操作不当的内存错误
- 操作性:简单易用,又功能强大