C++中的&和*

关于C艹中的&*的作用,其实是比较基础的知识,但是一段时间不碰就要忘(记性不好),所以要做点笔记方便查找。

&

&有两种用法,分别是在定义变量时作为引用和使用变量时作为取地址操作符。

引用

在声明变量时,在变量名前加入&,即表示为该变量类型的引用(左值引用,lvalue reference)。其中C++ Primer中特别强调:

引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。

其中引用必须在生命时赋值,而赋值的类型必须是一个对象。

1
2
3
4
int a = 1;

int &b = a; //正确
int &c = 2; //错误

引用在初始化赋值后,相当于绑定了其赋值的对象,并且无法让该引用重新绑定其他值。(C++ Primer中一直强调是绑定而非指向,这是很严谨的一种说法,避免混淆指针)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define LOGI(TAG, INFO) cout<<"TAG:"<<TAG<<" || "<<INFO<<endl;

int a = 4;
int b = 5;
int &r = a;
LOGI("r", r)
LOGI("r", &r)
LOGI("a", &a)
LOGI("b", &b)

r = b;
LOGI("r", r)
LOGI("r", &r)
LOGI("a", &a)
LOGI("b", &b)

如上,最终的打印为:

1
2
3
4
5
6
7
8
TAG:r || 4
TAG:r || 0x7fffa8aee308
TAG:a || 0x7fffa8aee308
TAG:b || 0x7fffa8aee30c
TAG:r || 5
TAG:r || 0x7fffa8aee308
TAG:a || 0x7fffa8aee308
TAG:b || 0x7fffa8aee30c

可以看到,引用r在声明时绑定了int类型的对象a,则其地址值一直跟a一致,无论后面对引用r进行什么操作,都相当于对a进行操作。

const引用

相关链接:C++中的顶层const

const引用一般简称为常量引用,意指该引用绑定的是一个常量对象,是一个底层const。

常量引用不止可以绑定常量对象,也可以绑定常量值。其中特殊的一点是,还可以绑定非常量对象。

1
2
3
4
int i = 1;
const int &r1 = i;
const int &r2 = 2;
const int &r3 = r1 * 2;

如上,常量引用r1可以绑定非常量对象i。常量引用本身是无法再进行修改操作的,但其绑定的非常量对象可以进行修改。

特别注意的是,比如数值型的变量之间可以相互赋值,虽然会丢失精度,如double型的值直接可以直接赋值到int类型上。因此:

1
2
3
4
5
6
7
8
double a = 3.14;
LOGI("&a",&a)
const int &r = a;
LOGI("r",r)
LOGI("&r",&r)
a = 5.14;
LOGI("r",r)
LOGI("&r",&r)

如上,最终的打印为:

1
2
3
4
5
TAG:&a || 0x7ffcb2c98968
TAG:r || 3
TAG:&r || 0x7ffcb2c98964
TAG:r || 3
TAG:&r || 0x7ffcb2c98964

可以看到,虽然表面上int型的常量引用r可以“绑定”double型对象a,但实际他们的地址并不相同。主要原因是编译器为了确保引用r可以绑定一个整数,在编译时增加了一个临时量对象。C++ Primer中的描述为:

所谓的临时量对象就是当编译器需要一个空间来暂存表达式的求值结果时临时创建的一个未命名的对象。C++程序员们常常把临时量对象简称为临时量。

因此,经过编译器编译后的代码可以理解为:

1
2
3
double a = 3.1f;
const int temp = a;
const int &r = temp;

因此,上面打印的引用r的地址值为临时量对象的地址值,而改变对象a的值,也不会改变引用r所绑定的对象的值。

取地址操作符

&用在已经声明的对象前面(注意不是在声明时使用),表示获取该对象的地址。这个比较常用,就不细说了。

*

*&一样有两种用法,分别是在定义变量时声明为指针和使用变量时作为解引用符。

指针

引用C++ Primer中对指针的定义:

指针(Pointer)是“指向(point to)”另外一种类型的复合类型。与引用类似,指针也实现了对其他对象的简直访问。然而指针与引用相比又有很多不同点。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内,它可以先后指向几个不同的对象。其二,指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

简单来说,指针是一种类型,用于指向另一个对象;而引用只是绑定对象。

1
2
3
int i = 1;
int *p = i;
int *pp;

声明一个指针,只需要在声明变量时加入*即可。

解引用符

*用在对象前面即表示为解引用符,解引用符只能用在指针类型的变量上。

C++ Primer中的定义:

对指针解引用会得出所指的对象,因此如果给解引用的结果赋值,实际上也是给指针所指的对象赋值。

setLayoutParams和onMeasure C++中typedef和指针结合时理解

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×