const_cast_weixin_30820077的博客-程序员秘密

技术标签: 操作系统  

也许大家都有过这样的疑惑: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是另外的一个变量

转载于:https://www.cnblogs.com/cavehubiao/p/3654614.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30820077/article/details/99378682

智能推荐

python语言程序设计9.1 计算平均值,标准差,中位数_坟前向日葵的博客-程序员秘密

from math import sqrtdef getNum(): nums=[] iNumStr=input("输入数字(回车退出):") while iNumStr !="": nums.append(eval(iNumStr)) iNumStr=input("输入数字(回车退出):") return numsdef mea...

不同数据库将时间字段格式化成‘YYYY-MM-DD‘_数据库日期转换为yyyy-mm-dd_追逐☞的博客-程序员秘密

orcale、postgresql格式化时间字段。sqlserver格式化时间字段。mysql格式化时间字段。

银联支付更换正式环境后报错存在风险而关闭了订单_PMJ520的博客-程序员秘密

不得不吐槽下银联了,到处都是坑,测试OK之后切换为正式环境,报错了像这样:解决方案:必须要在申请帐号时绑定的域名下才可以使用;并且不支持绑定域名下的其他二级域名;也可以联系商务绑定更多域名;

LEX和YACC的使用_c+lex+yacc+shell解释器_Augusdi的博客-程序员秘密

   Lex自动地表示把输入串词法结构的正规式及相应的动作转换成一个宿主语言的程序,即词法分析程序,它有一个固定的名字yyler,在这里yyler是一个C语言的程序。   Yylex将识别出输入串中的词形,并且在识别出某词形时完成指定的动作。   看一个简单的例子:写一个lex源程序,将输入串中的小写字母转换成相应的大定字母。   程序如下:   %%    [a-z] printf("%c"

libtorch学习笔记(17)- ResNet50 FPN以及如何应用于Faster-RCNN_fpn faster rcnn_王飞95的博客-程序员秘密

FPN,即Feature Pyramid Networks,是一种多尺寸,金字塔结构深度学习网络,使用了FPN的Faster-RCNN,其测试结果超过大部分single-model,包括COCO 2016年挑战的获胜模型。其优势是小尺寸对象的检测。torchvision中包含了ResNet50 FPN完整的源代码(这里参考的是torchvision 0.7.0里面的代码),这里就解读一下对应的实现,为了解释流畅,尽量采用ResNet50中的layer name,以及对应的参数:这里画了一个全局图,将

随便推点

eclipse里边找对应大括号的快捷键是_eclipse找到对应的括号_march1985的博客-程序员秘密

把你的光标移动到大括号左右,另外一个大括号就会有底色标记。你可以在括号的右边双击文本编辑区域,这样括号内的内容都会被选中(只有某些文本类型才有效,比如java,js),这样你也能清楚的看到一对大括号的位置。还可以将大括号里的内容收起来,在行号左边有+-号点击可以收放。查找对应的大括号,不知道有这个功能存在。其实我想说,是Ctrl + Shift+ P,

vmware 更新wmware Tools 工具_m_spider的博客-程序员秘密

首先下载VMware,普通的软件安装方法,一直下一步就可以了。然后下载ubuntu的镜像,安装的时候也是简单的安装。安装完成打开后,尴尬了这个界面真的是太小了,用着一点都不舒服。然后开始学习如何调整界面的大小。 首先打开虚拟机 (因为安装过,显示重新安装) 进入虚拟机的CD-Room 找到VMware Tools文件 按照网上的教程,把这个文件夹下所有的文件拷贝...

Libgdx的使用(12)——physics-body-editor_physics body editor_wkjsmx的博客-程序员秘密

Box2d是一个很出名的2d物理引擎,有C++、Java等等版本。libgdx对Box2D进行了很高效的封装,极大的降低了学习和使用成本。但是我觉得和Libgdx的UI库比起来,Box2D的使用始终比较复杂,单纯的物体降落什么的还好说,要是遇上一个特别复杂的物体,有时候就有点繁琐了。在网上游荡时发现了physics-body-editor,绝对堪称神器。phys

mysql语句中模糊查询_关于sql、mysql语句的模糊查询分类与详解,包括基本用法和mapper.xml文件里插入写法..._weixin_39645165的博客-程序员秘密

欢迎猿类加qq:2318645572,共同学习进步实际例子:ssm框架:service业务层-&gt;dao层-&gt;mappers.xml-&gt;junit/test测试1:service业务层(package)@Resourceprivate BooksDao bookDao;public List&gt; Service(String serachtitle, String serach...

HashSet 介绍_static_mkk的博客-程序员秘密

HashSet 介绍标签: java8源码 思路:内部就是用HashMap来存储数据.把set的值存放在map的key中.Haset 可以简单的理解为 HashMap 的key的集合. 因为其,依靠HashMap来完成各种操作.特点1.允许使用null,最多一个2.不保正元素顺序3.非同步的4.Iterator会触发快速失败机制签名public c...

前端进阶:vue中的computed和watch的异同_車句的博客-程序员秘密

原文链接前言心情很忐忑,当我写下这个标题。想起年初时在杭州求职,电面了一家武汉的公司,面试官就抛了这样一个问题。那时候还懵懵懂懂,就知道如何使用,并没有太清楚两者的区别。开始有时候写这些东西,真的怕误导了一些人,以下描述的异同,只是我个人的观点。如果有什么不当之处,还望各位博友指出~感谢最近研究vue.js数据双向绑定的原理,看了一些很好的文章,自己也跟着敲了几遍代码。又开始思...

推荐文章

热门文章

相关标签