持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
我们可以将引用来来引用一个常量类型的对象,这个引用其他类型并没有任何区别。不过有一点大家还是需要注意的,就是与变量的引用不同,引用常量的引用是不能改变其所引用对象的值的。
const int a = 2;
const int& ref_a = a;
这里定义一个常量 a 然后定义常量引用,需要注意一下 const 的位置
const int &ref_a = a;
ref_a = 3;
其实 ref_a 就是引用了变量 a 因为 a 是常量不能改变的,所以试图通过 ref_a 来修改 a 的值就会报错。
const int a = 2;
int& ref_a = a;
那么像上面用一个普通引用来引用一个常量也是行不通的,需要用一个常量引用来引用常量。不过可以用常量引用来引用一个不同变量、字面量或者一个普通表达式,如下
int a = 12;
//普通变量
const int &ref_a = a;
//字面量
const int &ref_b = 12;
const int &ref_c = ref_a * 2;
这里注意我们知道不同引用是无法引用一个字面量,不过常量引用则可以直接引用一个字面量。
int a = 2;
int& ref_a = a;
const int& ref_b = ref_a * 3;
int& c = ref_b * 2;
这里用普通引用来尝试引用一个常量引用,这样做也是行不通的。
这里对于引用初始化的正确性检查都是发生在编译阶段
double a = 3.14;
const int &ref_a = a;
上面 double 类型变量 a 赋值给常量 int 类型的引用,我们都知道对于一个普通引用类型是无法引用不同类型的变量,不过
int temp = a;
const int &ref_a = temp
首先编译器会创建临时 int 类型变量接受 double 类型的值,然后再将 int 类型常量引用引用到这个中间变量上。
int i = 10;
int* ptr_i = &i;
int*& ptr_ref = ptr_i;
std::cout << *ptr_ref << std::endl;
这里 ptr_ref 是指向 int 地址的指针 ptr_i 的引用,这样输出值 ptr_ref 接受的值为 i 变量保存的值,因此输出 *ptr_ref 为 10。
int i = 10;
int j = 5;
int* ptr = &i;
int*& ptr_ref = ptr;
ptr_ref = &j;
std::cout << *ptr << std::endl;
在此会输出 5, 也就是变量 j 的值,首先定义 int* 也就是 int 类型的指针变量 ptr,然后将变量的 i 的地址赋值给 ptr,接下来定义 int* 类型的引用 int*& 来引用变量 ptr。其实 ptr_ref 就是 ptr ,当将 j 的地址赋值给变量 ptr_ref 后当也就是等于修改 ptr 指针指向的内存地址,当用取值操作对 ptr 进行取值,自然也就是就拿到 j 变量的值。
int* const& ptr_ref = ptr;
我们来看 const 的位置,const 修饰的引用
ptr_ref = &j;
这个留个大家思考一下 2 次 ref_a 的输出结果
int main()
{
int a = 2;
const int& ref_a = a;
std::cout << ref_a << std::endl;
a = 3;
std::cout << ref_a << std::endl;
return 0;
}