卓航论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 257|回复: 3
打印 上一主题 下一主题

C++中四种类型转换 const_cast是否能改变常量

[复制链接]
[至尊红钻5级]发帖数量≥8000篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [至尊紫钻4级]金币≥20000个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 论坛元老
 UID:  7   [未点亮普号显示]钻石不足3个
 阁 分: 36567
 阁 望: 0
 阁 献: 0
 活 跃: 0
 发 贴: 12405 (0)
 阁 币: 24162  
性 别: I'm 火星人!
阅读权限: 90
在线时长: 0 小时
注册时间: 2016-10-16
最后登录: 2016-10-18
go
楼主
发表于 2016-10-17 16:22:49 |只看该作者 |倒序浏览
本帖发表于 2016-10-17 16:22:49...阅读 258 人...加油,亲爱的楼主:[db:作者]
we have four specific castingoperators:dynamic_cast, reinterpret_cast, static_cast and const_cast. Their format is to follow the new type enclosed between angle-brackets () and immediately after, the expression to be converted between parentheses.
dynamic_cast  (expression)
reinterpret_cast  (expression)
static_cast  (expression)
const_cast  (expression)
一、对C++中四种类型转换总结如下:
const_cast(expr)
用来移除对象的常量性(cast away the constness)
const_cast一般用于指针或者引用
使用const_cast去除const限定的目的不是为了修改它的内容
使用const_cast去除const限定,通常是为了函数能够接受这个实际参数
static_cast(expr)
编译器隐式执行的任何类型转换都可以由static_cast完成
当一个较大的算术类型赋值给较小的类型时,可以用static_cast进行强制转换。
可以将void*指针转换为某一类型的指针
可以将基类指针转换为派生类指针
无法将const转化为nonconst,这个只有const_cast才可以办得到
reinterpret_cast(expr)
“通常为操作数的位模式提供较低层的重新解释”也就是说将数据以二进制存在形式的重新解释。
int i;
char *p = "This is a example.";
i = reinterpret_cast(p);
//此时结果,i与p的值是完全相同的。
int *ip
char *pc = reinterpret_cast(ip);
// 程序员需要记得pc所指向的真实对象是int型,并非字符串。
// 如果将pc当作字符指针进行操作,可能会造成运行时错误
// 如int len = strlen(pc);
dynamic_cast(expr)
执行“安全向下”转型操作,也就是说支持运行时识别指针或所指向的对象,这是唯一个无法用旧式语来进行的转型操作。
dynamic_cast可谓是最严格的转换,static_cast次之,而reinterpret_cast则是最宽松的。如果你遇到不能将整型转变为函数指针的问题,你可以这样解决:
reinterpret_cast(nAddress);
注意LPFUN这里有个“&”符号,表示引用,C++的引用其实就是用指针实现的,而这些“转换”其实都是指针的转换,所以加上引用符号编译才能通过。
               
二、也许大家都有过这样的疑惑:const_cast可以去除一个常量的const属性,去除const属性后应该可以对“常量”进行修改,通过调试器发现内存中的值是被改变的,可是再传递这个“常量”的时候,值却一直保持原状,实在古怪,在Windows下用VC、尝试如此,在Linux下用g++尝试也如此,我原先以为和编译器的优化选项有关系,把所有优化选项关闭,照样没用,为什么?
写了个程序进行测试:
#include
using namespace std;
   
void Fun(int &value)
{
    cout
输出为:

可以看出打印的地址是一样的,而且奇怪的是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下测试也是同样的输出结果:

附录:
MSDN上关于四种cast的说明:
reinterpret_cast Operator
The reinterpret_cast operator allows any pointer to be converted into any other pointer type. It also allows any integral type to be converted into any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.
dynamic_cast Operator
The expression dynamic_cast( expression ) converts the operand expression to an object of type type-id. The type-id must be a pointer or a reference to a previously defined class type or a“pointer to void”. The type of expression must be a pointer if type-id is a pointer, or an l-value if type-id is a reference.
static_cast Operator
The expression static_cast  ( expression ) converts expression to the type of type-id based solely on the types present in the expression. No run-time type check is made to ensure the safety of the conversion.
const_cast operator
The const_cast operator can be used to remove the const, volatile, and __unaligned attribute(s) from a class.
分享到: QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏0 支持支持0 反对反对0

使用道具 举报

[至尊红钻3级]发帖数量≥1000篇 [至尊黄钻3级]威望≥500点 [至尊蓝钻1级]在线时间≥10小时 [至尊绿钻9级]贡献度≥80000点 [至尊紫钻9级]金币≥8000000个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 管理员
 UID:  1   [未点亮普号显示]钻石不足3个
 阁 分: 2147483647
 阁 望: 993
 阁 献: 2147483647
 活 跃: 0
 发 贴: 1532 (0)
 阁 币: 9430326  
性 别: I'm 火星人!
阅读权限: 200
在线时长: 46 小时
注册时间: 2016-10-14
最后登录: 2023-10-3
沙发
发表于 2016-10-18 00:02:00 |只看该作者
本回复帖发表于 2016-10-18 00:02:00,感谢爱情孤儿对本帖的认真回复,你的回复是对楼主莫大的鼓舞
没看完~~~~~~ 先顶,好同志

使用道具 举报

[至尊红钻2级]发帖数量≥100篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [未点亮至尊紫钻]金币不足100个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 注册会员
 UID:  36   [未点亮普号显示]钻石不足3个
 阁 分: 180
 阁 望: 6
 阁 献: 6
 活 跃: 0
 发 贴: 160 (0)
 阁 币: 2  
性 别: I'm 火星人!
阅读权限: 20
在线时长: 1 小时
注册时间: 2011-1-6
最后登录: 2016-10-21
板凳
发表于 2016-10-19 11:09:46 |只看该作者
本回复帖发表于 2016-10-19 11:09:46,感谢rrssttrst对本帖的认真回复,你的回复是对楼主莫大的鼓舞
学习了,谢谢分享、、、

使用道具 举报

[至尊红钻2级]发帖数量≥100篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [未点亮至尊紫钻]金币不足100个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 注册会员
 UID:  60   [未点亮普号显示]钻石不足3个
 阁 分: 179
 阁 望: 5
 阁 献: 6
 活 跃: 0
 发 贴: 160 (0)
 阁 币: 3  
性 别: I'm Boy
阅读权限: 20
在线时长: 0 小时
注册时间: 2011-1-6
最后登录: 2016-10-21
地板
发表于 2016-10-21 01:03:54 |只看该作者
本回复帖发表于 2016-10-21 01:03:54,感谢tulike对本帖的认真回复,你的回复是对楼主莫大的鼓舞
相当不错,感谢无私分享精神!

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1、请认真发帖,禁止回复纯表情,纯数字等无意义的内容!帖子内容不要太简单!
2、提倡文明上网,净化网络环境!抵制低俗不良违法有害信息。
3、每个贴内连续回复请勿多余3贴,每个版面回复请勿多余10贴!
4、如果你对主帖作者的帖子不屑一顾的话,请勿回帖。谢谢合作!

手机版| 百度搜索:vkee.pw

2012-2015 卓航旗下 GMT+8, 2024-6-16 17:14 , Processed in 4.981395 second(s), 30 queries . Powered by Discuz! X3.2  

禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.如遇版权问题,请及时联系站长(QQ:5213513)

今天是: | 本站已经安全运行: //这个地方可以改颜色

快速回复 返回顶部 返回列表