const_cast的疑点

const_cast的疑问
本帖最后由 lgbxyz 于 2014-03-25 13:48:15 编辑
const_cast主要用来暂时解除const限制。
下面程序中 变量b 为什么没有被修改,调用函数 my_sqrt时,他的引用被修改了,
引用被修改了,为什么原来的值不能被改变呢 ?
const_cast的疑点

#include <iostream>

void my_sqrt(const int &x)
{
const_cast<int &>(x) = x * x; //去掉了x的const限制,否则不能更改x的值
std::cout<<"x = "<<x<<std::endl;
}
int main(void)
{
int a = 5;
const int b = 5;

my_sqrt(a);
std::cout<<"a = "<<a<<std::endl;

my_sqrt(b);
std::cout<<"b = "<<b<<std::endl;

return 0;
}

/*---- 输出结果---------
x = 25
a = 25
x = 25
b = 5
-----------------------*/

------解决方案--------------------
常量被编译器直接替换成对应的值了,看下面编译出来的汇编的147行,直接替换成立即数了

141     leaq    -16(%rbp), %rdi
142     call    _Z7my_sqrtRKi
143     movl    $.LC2, %esi
144     movl    $_ZSt4cout, %edi
145     call    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
146     movq    %rax, %rdi
147     movl    $5, %esi
148     call    _ZNSolsEi
149     movq    %rax, %rdi
150     movl    $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi

------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

再解释一下x吧,为什么x是25
Quote: 引用:

x是个const引用,你将a传进去,x绑定在a上,a不是const的,去除了const限制,你可以通过x改a。但是你将b传入,b是const的,你去除了x的const限制,但是只是说你能通过x去改绑定的值,不过你的b还是const的啊,所以不能改。

上面已经说了,a没const限制,所以x去了const限制就能改a,但是b有const限制,你只是去掉了x的限制。。所以还是改不了b啊。。

这个我也觉得很奇怪,在内存里面,b占据的内存明明已经变成25了,出了函数之后却还是输出5

看汇编的时候,输出之后又有一个mov指令,说明它又变回5了。
------解决方案--------------------
C++编译器,已经初始化的 const 会彻底看做常量(常量表达式)
编译的时候,只要是直接使用 该常量的名字,就会替换成常量本身;
至于存储这个数据的空间,只有通过间接访问的,才访问
这个内存,才能获得被修改的数据。

这是由于你的行为不一致,造成代码的行为也不一致。

因为你自己定义,这个数据为常量,而后通过其他途径,去企图修改这个常量。
C++允许你这么做,却不在保证你的程序的行为是正确的,可控的了。