• 指针修改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 对象,就进行替换,而不是从内存中提取最新的值。





  • 相关阅读:
    Docker
    Alfred Workflow
    AWS Lambda
    XPath
    WebMagic
    Splash
    Selenium
    代理服务器
    JSONPath
    Sqlserver 查询分组 记录
  • 原文地址:https://www.cnblogs.com/wangpei0522/p/3883750.html
Copyright © 2020-2023  润新知