C++的引用和指针

学过C语言的指针,我们知道,指针变量存的是其他变量的地址,其大小为4Byte(32位操作系统下;如果是64位操作系统,则为8Byte)。我们可以通过指针来间接修改变量的值。

在C++中,引用的应用场景与指针类似。引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

类型 & 引用变量名 ( 对象名 ) = 引用实体。
void test()
{
    int a=0;
    int& b=a;
    b+=1;
    cout<<a<<endl;
}

此时函数的调用结果为1,因为b是变量a的别名,两者指向同一块空间。

一、引用的有三个特性:

1、引用在定义时必须初始化(引用不能为空)。

2、一个变量可以有多个引用。

3、引用一旦引用一个实体,再不能引用其他实体。举个例子:看下面这个代码

void test()
{
    int a=0;
    int& b=a;
    int z=10;
    b=z;
    cout<<a<<endl;
}

这段代码里b=z的作用是将z这一块空间里的值赋值给b指向的空间(即为a指向的空间),而不是将b作为z的别名。如果要将b作为z的别名,则需要重新定义b作为z的别名,但在一个程序中不能出现重定义。所以引用不能改变指向。

二、使用引用时要注意权限问题

权限只能缩小或平移

1、权限平移很容易理解,顾名思义引用类型必须和引用实体同种类型的。

2、权限的缩小。下面的代码中,b是a的别名,但是有const修饰,所以不能通过b来对a进行修改,只能通过b来得到a的值。

void test()
{
    int a=0;
    const int& b=a;
}

3、权限不能放大。如下面这个例子就会报错。

void test()
{
    const int a=0;
    int& b=a;//这属于权限的放大,即a是常变量(不能改变),而b的实体类型定义的为int,即可以通过b来修改a的值,这样做是非法的,编译器会报错
}

4、其实C语言里也有相似的场景如下:指针p1里存放的是a的地址,且不能通过p1来修改a的值。

而p2指针里包含的是p1存放的地址,且int*前没有const修饰,则可以通过p2对*p1进行修改。

void test()
{
    int a=0;
    const int* p1=&a;
    int* p2=p1;//这里编译器会报错
}

此外,这里还要注意的是,如果是const int* p1=&a;则不能通过*p1来修改a的值,但是可以改变p1所指向的空间。如果是int* const p1=&a;则可以通过*p1来修改a的值,但是不能改变p1所指向的空间。

三、引用时要注意“临时变量的问题”。

哪些场景下会产生临时变量呢?

1、类型转换(包括隐式类型转换和强制类型转换等)。

2、表达式。

临时变量具有常属性,因此要用const修饰。

void test()
{
    double a=12.34;
    const int& b=a;
    int x=0,y=1;
    const int& z=x+y;//如果写int& z=x+y会报错
}

四、引用和指针的不同点

1. 引用在定义时必须初始化,指针没有要求。

2. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型 实体。

3. 没有 NULL 引用 ,但有 NULL 指针。
4. sizeof 中含义不同 引用 结果为 引用类型的大小 ,但 指针 始终是 地址空间所占字节个数 (32 位平台下占4个字节 )。
5. 引用自加即引用的实体增加 1 ,指针自加即指针向后偏移一个类型的大小。
6. 有多级指针,但是没有多级引用。
7. 访问实体方式不同, 指针需要显式解引用,引用编译器自己处理。
8. 引用比指针使用起来相对更安全。
9.引用在语法上是不开空间的,是其他变量的别名,而指针是开空间的。(实际上引用在底层也是要开空间的)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值