指针修改const对象

我们都知道const的作用是声明变量为常量,在程序中除非显示转换,否则无法修改声明为const的对象。

本文针对显示修改的情况,提醒了一种隐式的错误,以及解决办法。

考虑下面的代码:

#include<iostream>
int main(){
  const int a=0;
  int         *p=const_cast<int*>(&a);//&a返回int *,const_cast<int*>显示转换为int*.
  *p             =1;  
  int           b=*p;
  int           c=a;
 std::cout<<“b: "<<b<<std::endl<<"c: "<<c<<std::endl;
 std::cout<<&a<<" "<<p<<std::endl;
return 0;     
}

 

输出的结果是:

b: 1

c: 2

0x7fffe27cd63c 0x7fffe27cd63c

问题就在这里,我们通过*p改变了a的值,并且检查指针指向的地址和变量的地址一致。但是打印const对象的赋值,发现最终的值仍然没有改变。

如果这发生在了程序的某个角落,我们通过*p改变了a的值,但是在下一次用a的时候,得到的结果仍然没有改变,这将发生不可预测的问题。这再一次提醒了我们,不要轻易使用强制类型转换,这往往会导致一些我们难以察觉的错误。

解决这个问题很简单,利用volatile修饰符:让变量a每次访问都强制到内存中读取最新的数据。

#include<iostream>
int main(){
  const volatile int a=0;
  int         *p=const_cast<int*>(&a);//&a返回int *,const_cast<int*>显示转换为int*.
  *p            =1;  
  int           b=*p;
  int           c=a;
 std::cout<<“b: "<<b<<std::endl<<"c: "<<c<<std::endl;
return 0;     
}

输出结果是:

b: 1

c: 1

想来读者已经想到了原因:const修饰的对象,编译器进行了符号替换。下文中用到了const 对象,就进行替换,而不是从内存中提取最新的值。

 





 

posted @ 2014-07-31 22:56  P.wang  阅读(1469)  评论(0编辑  收藏  举报