C++中的引用

本文深入探讨了C++中的引用概念,包括引用的声明、意义、使用方式及常引用特性。详细阐述了引用如何作为其他变量的别名、在函数参数中的应用以及与指针的区别。同时,解释了常引用的含义、初始化方式及其与常量的关系。最后,通过实例展示了引用在函数返回、三目运算符中的特殊用法。
摘要由CSDN通过智能技术生成

思考:对于一段连续的存储空间只能有一个别名吗?

在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++中引用的本质是一个指针常量



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值