• const_cast


    也许大家都有过这样的疑惑:const_cast可以去除一个常量的const属性,去除const属性后应该可以对“常量”进行修改,通过调试器发现内存中的值是被改变的,可是再传递这个“常量”的时候,值却一直保持原状,实在古怪,在Windows下用VC、尝试如此,在Linux下用g++尝试也如此,我原先以为和编译器的优化选项有关系,把所有优化选项关闭,照样没用,为什么?

    写了个程序进行测试:

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <iostream>
    using namespace std;
         
    void Fun(int &value)
    {
        cout << "Fun(val) = " << value << endl;
    }
         
    int main(void)
    {
        const int val = 100;
         
        int *ptr = const_cast<int *>(&val);
        *ptr = 200;
        cout << &val << endl;
        cout << ptr << endl;
        cout << "val = " << val << endl;
        cout << "*ptr = " << *ptr << endl;
         
         
        int &ref = const_cast<int &>(val);
        ref = 300;
        cout << "val = " << val << endl;
        cout << "ref = " << ref << endl;
         
        Fun(const_cast<int &>(val));
         
        return 0;
    }

    输出为:

    可以看出打印的地址是一样的,而且奇怪的是val还是等于100,而通过*ptr打印出来的却是更改后的200,再者Fun函数打印的是300,即被引用再次修改了一次,在打印语句附近设置断点并调试反汇编,截取一段如下图:

    可以明显地看出系统是对val这个const进行了预处理般的替换,将它替换成“64h”(十六进制的64就是十进制的100),即在编译生成的指令中val就已经被替换成100了,其实加const只是告诉编译器不能修改而不是真正地不可修改,如果程序员不注意而去修改了它会报错,现在我们利用const_cast去除了常量性,然后通过指针和引用对其进行了修改,所以通过指针打印或者引用传参的时候就能看出其内存确实变化了,但为了保护val这个变量本来的const特性,所以每次我们使用val时,系统都将其替换成初始值100,确保了val还是“不可变”的。记住,只有当const限定符加在已经初始化的全局变量前面的时候,此时变量处在.rodata段(linux下),才是真正的不可修改,否则通过指针都是可以修改的,虽然编译过程中会产生警告。

    在linux下测试也是同样的输出结果:

    注意的是:const_cast可以转换非指针类型,但是const int a=100; int c=const_cast<int>(a);这样是错的,必须是int c=const_cast<int&>(a);但此时不同于int &c=const_cast<int&>(a);这时的c是另外的一个变量

  • 相关阅读:
    ExecuteNonQuery()返回值
    GridView导入至EXCEL (报错处理:只能在执行 Render() 的过程中调用 RegisterForEventValidation)
    mysql 远程登录
    四舍六入 银行家算法
    linux-grep-tail-find
    spring 事务注解
    aop execution 表达式解析
    事务有效条件
    oracle 日期取 月 日
    spring cloud 定时任务
  • 原文地址:https://www.cnblogs.com/cavehubiao/p/3654614.html
Copyright © 2020-2023  润新知