思考:对于一段连续的存储空间只能有一个别名吗?
在C++中新增加了引用的概念
.引用可以看做一个已定义变量的别名
.引用的语法:Type& name = var;
例1:
int a = 4;
int& b = a; //定义引用b来引用a,意味引用b成为了a的别名,a和b指向了同一段内存空间
b = 5; //5赋值给b就等价于与5赋值给a
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("&a = %08X\n",&a);
printf("&b = %08X\n",&b);
Tip:普通引用在声明时必须用其他的变量进行初始化: int& b = a;
int& b;
b = a; //报错,引用b没有声明时初始化
int& b = 4; //报错,必须用其他的变量进行初始化,不能用值初始化
引用的意义
.引用作为其他变量的别名而存在,因此在一些场合可以代替指针
.引用相对于指针来说具有更好的可读性和实用性
swap函数的实现对比
Tip:引用作为函数参数声明时不进行初始化
swap(&a, &b)第一感觉像是在叫唤a的地址和b的地址,可读性差
swap(a, b)将引用作为参数可读性更好
const引用
.在C++中可以声明const引用
.const Type& name = var;
.const引用让变量拥有只读属性
int a = 4;
const int& b = a;
b = 5; //报错,const引用b只读属性,不能够当成左值来使用
可以通过指针int* p = (int*)&b; *p = 5; 来修改常引用b的值
当使用常量对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
const int& b = 1; //常量1对常引用b初始化(常量可以对常引用进行初始化,但是不能对普通引用初始化),这种情况编译器会为常量1分配4字节空间并把1放进去,编译器把b作为这4字节连续空间的别名
int* p = (int*)&b; //取b地址合法,b必然代表一片空间,编译器为常量1分配的空间
*p = 5;
printf("b = %d\n",b); //输出5,绝对是一个只读变量而不是const常量,因为通过b取到的地址来赋值的时候值真的改变了,这不是一个常量的行为
如果改成常量
const int b = 1;
int* p = (int*)&b;
*p = 5;
printf("b = %d\n",b); //输出1,结果不会改变,因为编译器从符号表里面取得常量值
Tip:使用常量对const 引用初始化后将生成一个只读变量,这个只读变量只有一个名字,就是引用的名字,编译器看到const int& b = 1,就会生成一个只读变量,这个只读变量的名字就是b,这个只读变量跟C语言里面的const只读变量是一个意义
引用有自己的存储空间吗?有
struct TRef
{
int& a;
int& b;
};
int main()
{
printf("sizeof(TRef) = %d\n",sizeof(TRef)); //输出8
return 0;
}
引用在C++中的内部实现是一个常指针
Type& name <--> Type* const name
struct TRef
{
int& a; // ==> int* const a;
int& b; // ==> int* const b;
};
C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同
从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间,这是C++为了实用性而做出的细节隐藏
当函数返回值为引用时
.若返回栈变量
.不能成为其他引用的初始值
.不能作为左值使用
.若返回静态变量或全局变量
.可以成为其他引用的初始值
.既可作为右值使用,也可作为左值使用
例:int& f() //返回静态变量
{
static int a = 0;
return a;
}
int& g() //返回栈变量
{
int a = 0;
return a;
}
int main()
{
int a = g();
int& b = g();
f() = 10;
printf("a = %d\n", a);
printf("b = %d\n", b); //b输出随机值
printf("f() = %d\n", f());
}
C++对三目运算符做了什么?
当三目运算符的可能返回值是变量时,返回的是变量引用
当三目运算符的可能返回中有常量时,返回的是值
int a = 1;
int b = 2;
(a<b?a:b) = 3; //正确,返回a或b的引用,可以作为左值使用
(a<b?1:b) = 3; //错误,可能返回值中有常量,返回的是值,不能作为右值使用
小结
bool类型是C++新增加的基础类型,其值只能是true和false
C++中的引用可以看作变量的别名来使用
C++中的常引用可以使得一个变量拥有只读属性
C++中的常引用可以用常量初始化而得到一个只读变量
C++中引用的本质是一个指针常量