引用的本质就是指针,下面两行代码的底层逻辑是一致的
int *p = &a
int &ref = a
如果添加 const 限制词,表示不能通过 *p
或 ref
间接修改 a
的值
const int *p = &a
const int &ref = a
// 等价于
int const *p = &a
int const &ref = a
一般常用于参数声明,如
void foo(const int *p)
void foo(const int &ref)
如人们所知,引用只能指向变量。但添加 const 关键字的引用,可以指向临时值
int &ref = a // ok
int const &ref = a // ok
int &ref = 10 // error
int const &ref = 10 // ok
但是需要注意,非 const 引用不能指向 const 变量
const int a = 10
int &ref = a // error
int const &ref = a // ok
若 const 出现在 *
号后面,就代表指针变量 p
本身不可被修改
int* const p = &a
*p = 20 // ok
p = &b // error
因此发现,const 关键字将修饰它右边的第一个元素。
int *p = &a
int **pp = &p
const int *p = &a
const int **pp = &p
最后一片代码中的 pp
类型为 const int**
,表示 **pp
不可修改。pp
、*pp
可以修改,其中 *pp
指向指针变量 p
。
int* const &ref = p
// 等价于
int* const *pointer = &p
表示 pointer
引用了一个 int*
类型的变量。
*pointer
改变指针 p
的指向;**pointer
改变 *p
的值;ref
不可修改,*ref
可以修改。const int* &ref = p
// 等价于
const int* *pointer = &p
由于 const 修饰它右边的第一个元素,因此 pointer
的类型为 const int**
。
**pointer
不可修改,*pointer
可以修改;*ref
不可修改,ref
可以修改。// 以下两种声明都支持
int* p = &a
const int* p = &a
const int* const &ref = p
// 等价于
const int* const *pointer = &p
从后往前看,指针 *pointer
指向了一个 const int*
类型的变量。
*pointer
被 const 修饰,因此无法通过 *pointer
间接修改 p
的指向,故 ref
无法修改;int*
类型被 const 修饰,因此无法通过 **pointer
间接修改 *p
的值,故 *ref
无法修改;const int**
变为了 const int*
类型,又因为 const 具有向上兼容性,故同时支持 int*
与 const int*
两种类型。