const关键字修饰的变量保存在栈上,一般情况下不能被修改。但这并不意味着没有办法,我们可以使用 const_cast 操作符来取消常性。
1、const_cast 的使用
假设我们定义了一个int类型的变量,并使用const关键字修饰。一般情况下,便是是指针也无法修改变量 a 对应的值。
const int a = 10;
int* p = &a; //报错:const int *" 类型的值不能用于初始化 "int *" 类型的实体
现在我们的目的是修改变量 a 对应的内容,我们需要获取到 a 的地址,然后取消其常性
const int a = 10;
int* p = const_cast<int*>(&a); // 将 &a 的类型转换成 int*,然后赋值给p
*p = 20;
2、使用 const_cast 的注意事项
编译器优化:在使用const_cast操作符转换之前,编译器觉得变量 a 被const关键字修饰,一般而言就不会被修改,为了提升效率,直接将变量a对应的值保存到寄存器,如此一来,每次CPU要用的时候,无需特地去内存里取。
问题出现:尽管内存中的值已经被修改成 20,但是CPU屏蔽了变量a的变化,直接从寄存器里取,导致读取到的值依然是 10。这是被编译器优化以后的结果。(指针p 不是const类型的,每次都是从内存里取)
提出方案:既然编译器屏蔽了内存的变化,我们可以使用volatile关键字来限制这种优化,让CPU每次都从内存中读取。