const_cast去除const限制,同一片内存
本质很简单,但一些优化 和 编程上的错误,却让人看不清本质。
const int a = 10;
cout<<a<<endl; //10 //a = 20; //编译出错
const_cast<int&>(a) = 20; //转化成引用
cout<<"a: "<<a <<endl; //a的结果依然是10,a的内容没有变化?
可以看到a的值没有变化,依然是10。为什么呢?难道是新的内存,修改的是临时值? 但引用应该只是别名。
转换成指针看看地址
//int * p = &a; //编译出错
int * p = const_cast<int*>(&a);
*p = 20;
cout<<"a: "<<a << " a address:"<< &a <<endl; //10
cout<<"*p:"<<*p<<" p content:" <<p<< " p address: "<<&p<<endl; //20
//但p指向的是a的地址,两个内容应该 一致,所以是由于编译器的优化。
看到a的值没变,但*p变化了。而&a 与p 的内容一样,即p就是指向a的,两个是同一片内存,但打印出来的内容不一致,考虑由于编译器优化的原因。
volatile const int b=11;
cout<<"b:"<<b<<endl;
const_cast<int&>(b) = 22;
cout<<"b: "<<b << " b address:"<< &b <<endl; //22好了,引出新问题,为什么地址为1
printf("printf:%p\n",&b); //可以打印出地址
好了,加上volatile之后,不让编译器优化,每次都去内存中取值就正确了。
所以const_cast转化成引用或指针后,扔指向的是原来的内存,可以修改内存中的数据。
注:这里有一个新的发现,打印&b, b的地址的时候,用cout打印出1,printf打印出地址。这是为什么呢?仍是编译器的优化吗?
2.一些错误导致本质不清。
volatile const int b=11;
int bk = const_cast<int&>(b);
bk = 22;
cout<<"b: "<<b << " bk: "<< bk <<endl;
// b: 11 bk:22
仔细看,可以知道,修改的是变量bk的值,并没有修改b所只内存的值。虽然是引用,但bk没有申明为引用,是个新的变量。
可能本意是 int& bk = const_cast<int&>(b);
因此,很多错误,导致原本看清的本质变得模糊,甚至开始怀疑。
在测试的时候,必须保证你的代码是你原本想要的样子,才能继续测试你怀疑的真相!
const_cast去除const限制,同一片内存的更多相关文章
- 关于const和define的内存分配问题的总结
关于const和define的内存分配问题 const与#define宏定义的区别----C语言深度剖析 1, const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静 ...
- const 和 const_cast
对于const变量,我们不能修改它的值,这是这个限定符最直接的表现.但是我们就是想违背它的限定希望修改其内容怎么办呢?下边的代码显然是达不到目的的: ; int modifier = constant ...
- C++中四种类型转换以及const_cast是否能改变常量的问题
we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. ...
- C/C++(C++内存管理,内联函数,类型转换,命名空间,string类)
---恢复内容开始--- 内存管理 new/delete C语言中提供了 malloc 和 free 两个系统函数,#include "stdlib.h"库函数,完成对堆内存的申请 ...
- C++标准转换运算符const_cast
前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述.C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor ...
- 【转】C++标准转换运算符const_cast
const_cast转换符是用来移除变量的const或volatile限定符. 对于const变量,我们不能修改它的值,这是这个限定符最直接的表现.但是我们就是想违背它的限定希望修改其内容怎么办呢? ...
- C++标准转换运算符
C++类型转换在实际编程中会经常使用,其实,本质上对象的类型用来解释(interpret)对象.因为,每个对象都占据一块内存空间,这块内存空间存放了一段二进制数据.通过标记该对象的类型,告诉如何看待这 ...
- C++Primer学习——类型转换
无符号之间的运算 当一个是无符号类型,另外一个是带符号类型: 如果无符号不小于带符号,那么带符号转换成无符号. 如果无符号小于带符号,当无符号类型的所有值都能存到带符号中时,则无符号转换成带符号,否则 ...
- c++ 中的符号与关键字
符号按照符号的ASC码数值从小到达排列,关键字按照英文字母排序. & [38] 位运算:取地址:左值引用[指针.引用都是可以做类型转换的] #include <iostream> ...
随机推荐
- 原来是adblock惹的祸
一个在本地开发好的网站,放到服务器就不行了.花了好几个小时的时间,最后试着把adblock关了,然后正常了.
- [UML] Use Case 是什么
虽然每个人使用系统的场景有所差异,但是若用户的目标是相同的,则其场景会极为类似.那么这些类似的场景的集合就是类,这种类就称为Use Case.其实例就是场景
- 理解Java垃圾回收
stop-the-world 原文链接:http://www.cubrid.org/blog/de... 了解Java的垃圾回收(GC)原理能给我们带来什么好处?对于软件工程师来说,满足技术好奇心可算 ...
- python全栈开发- day14列表推导式、生成器表达式、模块基础
一.列表推导式 #1.示例 数据量小 egg_list=[] for i in range(10): egg_list.append('鸡蛋%s' %i) egg_list=['鸡蛋%s' %i fo ...
- CSS限制
http://www.cnblogs.com/YanPSun/archive/2012/03/16/2400141.html
- 基于Android的串口聊天室 (基于tiny4412) 一
一.平台介绍 硬件平台: tiny4412ADK + S700 4GB Flash Android版本:Android-5.0.2 Linux版本: Linux-3.0.86 Bootloader:S ...
- 重要的ui组件——Behavior
v7包下的组件类似CoordinatorLayout推出也有一段时间了,大家使用的时候应该会体会到其中很多的便利,今天这篇文章带大家来了解一个比较重要的ui组件——Behavior.从字面意思上就可以 ...
- 【微信】微信小程序 微信开发工具 创建js文件报错 pages/module/module.js 出现脚本错误或者未正确调用 Page()
创建报错pages/module/module.js 出现脚本错误或者未正确调用 Page() 解决方法: 在js文件中添加 Page({ })
- select 下拉框的选中项的change事件
HTML文件 <span style="float: left;">类 型: <select id="type" class=& ...
- C#中 protected internal 和 internal 的区别
http://kudick.blog.163.com/blog/static/1666066320091055414453/ DoDo: protected: 爷爷有一张银行卡,爸爸可以用,儿子也可以 ...