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是另外的一个变量

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

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

智能推荐

【Azkaban】Azkaban入门解析_azkaban执行mapreduce任务-程序员宅基地

文章浏览阅读7.2k次,点赞21次,收藏73次。一、Azkaban概述Azkaban是由Linkedin开源的一个批量工作流任务调度器。用于在一个工作流内以一个特定的顺序运行一组工作和流程;Azkaban定义了一种KV文件格式来建立任务之间的依赖关系,并提供一个易于使用的web用户界面维护和跟踪你的工作流二、Azkaban的功能特点1、提供功能清晰,简单易用的Web UI界面2、方便上传工作流3、提供job配置文件快速建立任务和任务之..._azkaban执行mapreduce任务

Chromium的智能指针/引用计数/Callback/Bind_chromium为什么用bind-程序员宅基地

文章浏览阅读6.4k次。本文算是个笔记整理,不解释基本概念,有做相关工作的人才看懂哦。一、自动释放指针智能指针分两类,对有和没有引用计数实现的类做区分。没有引用计数的类,使用scoped_ptr。这个模板类中的D是指Deleter,代表如何删除T。引入Deleter最简单的原因就是对数组需要使用delete[]操作符,实际上有4个默认的Deleter。3个Deleter都是通过重载括号运算符来执行实际的delete操作,_chromium为什么用bind

透视城市“生命线” MapGIS地下管线三维建模工具_三维管线质检工具gis-程序员宅基地

文章浏览阅读1k次。城市是繁忙的,昨夜的浮尘还未落定,新一天的晨曦又接替了灯光,人们匆匆地开启了新一天的生活,在车水马龙中穿梭,在楼宇林立间工作生活,一切都是匆匆而又有条不紊。繁忙的背后还是繁忙,水、电、燃气、热量、信息都在通过各种管线一刻不停地流向城市的每一个角落,那些深埋在地下的管线就是城市的“生命线”,输送城市运行必需的“血液”。在看不见的城市地下世界,这些管线埋藏有多深?各自通向哪里?管线运行维护,城市工程规划、设计、施工和管理,城市应急指挥和抢险,如何获取完整、准确、现势的地下管线信息?..._三维管线质检工具gis

python设计模式5-原型模式_python 原型模式-程序员宅基地

文章浏览阅读507次。1. 原型模式(Prototype)介绍UML类图原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype类需主要实现clone方法。原型模式是一种比较简单的模式,也非常容易理解。在实际应用中,原型模式很少单独出现,经常与其他模式混用。原型模式的优点及适用场景使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。使用原型模式的另_python 原型模式

Nginx 学习笔记总结(一)_whereis nginx-程序员宅基地

文章浏览阅读4.7k次,点赞2次,收藏42次。1. 在开发中,Nginx担任什么角色?2. 什么是Nginx?3. Nginx功能 之 反向代理3.1 什么是正向代理?3.2 什么是反向代理?3. Nginx功能 之 负载均衡4. Nginx功能 之 动静分离5. Nginx安装5.1 window安装5.2 linux安装6. Nginx命令7. Nginx 实战演示7.1 启动多台tomcat服务器7.2 Nginx配置的详解_whereis nginx

solr5.3.1 导入mysql数据-程序员宅基地

文章浏览阅读108次。1 从官网下载solr进行安装,安装过程略过(我下的版本是5.3.1) 2新建mysql数据库,然后建表 3 进入solr安装目录启动solr 4 创建core 在目录下会见到刚才新建的core的文件夹 进入 mycore2/conf,修改schema.xml(见附件),然后修改solrconfig.xml添加如下requestHandler&lt;requestH..._solr 5.3.1 无法定时拉取后端数据

随便推点

JNA实战笔记汇总(二)——JNA和C / C ++的数据类型映射(dll函数回调、结构体、指针)_vixhz_initsdk-程序员宅基地

文章浏览阅读1.2w次,点赞6次,收藏80次。目录JNA技术难点1、函数回调2、结构体3、指针JNA技术难点有过跨平台、跨语言开发的程序员都知道,跨平台、预研调用的难点,就是不同语言之间数据类型不一致造成的问题。绝大部分跨平台调用的失败都是这个问题造成的。关于这一点,不论何种语言、何种技术方案都无法解决这个问题。JNA也不列外。上面说到接口中使用的函数必须与链接库中的函数原型保持一致,这是JNA甚至所有跨平台调用的..._vixhz_initsdk

QEMU/KVM原理概述_kvm qemu-程序员宅基地

文章浏览阅读5.6k次。1. QEMU与KVM 架构qemu 和 kvm 架构整体上分为 3 部分,对应着上图的三个部分 (左上、右上和下),3 部分分别是 VMX root 的应用层,VMX no-root 和 VMX root 的内核层(分别对应着左上、右上和下)VMX root: 宿主机根模式,CPU 在运行包括 QEMU 在内的普通进程和宿主机的操作系统内核时,CPU 处在该模式。VMX no-root: 宿主机非根模式,CPU 在运行虚拟机中的用户程序和操作系统代码的时候处于 VMX no-root 模式注:_kvm qemu

数据库设计之网上书店系统-程序员宅基地

文章浏览阅读2.2w次,点赞59次,收藏467次。版权声明:对于本博客所有原创文章,允许个人、教育和非商业目的使用,但务必保证文章的完整性且不作任何修改地以超链接形式注明原始作者、出处及本声明。 博客地址:http://blog.csdn.net/shuxiao9058 原始作者:季亚一、概要设计2.1意义伴随着信息化的发展,计算机走进了千家万户,人们的交流变得方便,方便了网民的生活!此外,伴随着卓越、当当、淘宝..._订单属性

tcpdf 显示汉字-程序员宅基地

文章浏览阅读300次。原文来自零度科技最近在做将网页内容输出成pdf文档方面的一个项目,找了好多类,php_pdflib,fpdf,HTML_topdf等等,不过最终还是发现这个好用,究其汉字处理方面发现了写一篇文章,就抄过来了,以供大家参考。 TCPDF是一个用于快速生成PDF文件的PHP5函数包。TCPDF基于FPDF进行扩展和改进。支持UTF-8,Unicode,HTML和..._tcpdf 汉字 粗

初识React及React开发依赖介绍_react依赖包-程序员宅基地

文章浏览阅读8.5k次,点赞79次,收藏82次。React是什么呢?相信每个做开发的人对它都或多或少有一些印象;这里我们来看一下官方对它的解释:用于构建用户界面的 JavaScript 库;目前对于前端开发来说,几乎很少直接使用原生的JavaScript来开发应用程序,而是选择一个JavaScript库(框架)。在过去的很长时间内,jQuery是被使用最多的JavaScript库;在过去的一份调查中显示,全球前10,000个访问最高的网站中,有65%使用了jQuery,是当时最受欢迎的JavaScript库;但是,目前甚至已经处于淘汰的边缘了;_react依赖包

kafka和flume整合_kafka与flume1.60的整合消费不了数据-程序员宅基地

文章浏览阅读290次。关于Flume 的 一些核心概念:组件名称 &nbsp; &nbsp;功能介绍Agent代理使用JVM 运行Flume。每台机器运行一个agent,但是可以在一个agent中包含多个sources和sinks。Client客户端生产数据,运行在一个独立的线程。Source源从Client收集数据,传递给Channel。Sink接收器从Channel收集数据..._kafka与flume1.60的整合消费不了数据

推荐文章

热门文章

相关标签