C++ const reference

因为这个概念的中文翻译和绕口令一样所以直接用英文代替

  • const reference:引用本身是const的,比如const int &r1 = 1r1就是一个const reference,换句话说r1的值不能被更改(但是我们可以更改r1指向的值,当r1指向的值被更改,那么r1的值也被更改)

引用
引用和指针抛开底层不谈(引用底层也是指针实现的),引用和指针变量的最大区别就是引用绑定了被引用值,当引用发生变化,被引用的值也发生变化,这个在指针变量中是不可能的如下代码

std::string s = "hello world"; 
std::string& s1 = s; //引用s1和变量s绑定
s1 = "123456"; //更改s1
std::cout << s << std::endl;//输出123456,表明通过引用s1改变了被引用值s

想象一下我们传入一个引用到函数中,假如函数对引用做了一些我们未知的操作,那么被引用的值也会发生变化,此时程序就变得不可控,所以为了杜绝这个情况发生,引入了关键字const

const reference

故名思意就是我们引用是const的,换句话说引用的值不能被更改(当然我们可以更改被引用的值达到更改引用值的目的)如下代码

std::string s = "hello world"; 
const std::string& s1 = s;
s1 = "123456"; //error!!! 引用s1是const的我们不能更改引用s1的值

假如将引用s1传入函数中,函数中任何对引用s1赋值更改的操作都是错误的,所以在函数内不可能更改s1,进一步不能更改s1引向的对象的值,我们只能通过在函数外部更改s1引向的对象的值达到更改const reference s1值的目的,当然这个操作在函数外部执行,说明我们已经知晓我们要干什么如果出现错误导致引用s1的函数出现不可知行为说明是我们设计的bug

std::string s = "hello world"; 
const std::string& s1 = s; //将const reference s1指向一个非const的对象
s = "123456"; //更改const reference s1指向的对象s的值
std::cout << s1 << std::endl; //输出123456发现值已经通过s进行更改

综上所述const reference只是约束引用本身,不能通过引用去更改被引用的值

当然const reference也可以指向一个const变量或者右值

const std::string& s1 = "hello world"; //指向右值
const std::string s = "111"; //常量
const std::string& s1 = s; //指向常量



扩展

我们上面讲了引用,这里扩展一下指针,在C语言中有一下几个概念

  • 常量指针:从概念来说这是一个指针,指向一个常量比如const int* i
  • 指针常量:这是指针本身是一个常量比如int * const i

常量指针代码如下

int a = 1;
int b = 2;
const int* i = &a;
*i = 2; // error
i = &b;

我们看错误代码得知不能通过i去改变i指向的内容,有点绕口,因为i指向a这个内存地址,常量指针就是不能通过指针去改a的值,假如i不是常量指针那么就可以通过i去更改a的地址

指针常量代码如下

int a = 1;
int b = 2;

int*  const i = &a; //指针常量
i = &b;//error!!!因为i是常量

因为指针i本身是常量所以我们不能更改i的值

总结

指针变量和引用的区别,因为指针变量本身是一个变量,所以改变其值不会改变其指向内存区域的值,而引用可以看成"绑定"当一个引用指向一个内存区域(“绑定”)后,改变这个引用的值会顺带改变引用指向的对象的值,因此const和引用的组合要比const和指针的组合约束要大,导致const和引用的组合就只有const reference

你可能感兴趣的:(c/c++,c++,开发语言)