一、const_cast:只影响类型修饰符const,volatile
用法:const_cast<type_id>(expression)

该运算符用来修改类型的const或volatile属性。除了const或volatile修饰之外,type_id和expression的类型是一样的。

  • 常量指针被转化成非常量指针,并且仍然指向原来的对象;
  • 常量引用被转换成非常量引用,并且仍然指向原来的对象;
  • 常量对象被转换成非常量对象。
二、static_cast:
  • 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
  • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • 把空指针转换成目标类型的空指针。
  • 把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作。
三、reinterpret_cast:
  • 操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。
  • 所有映射中最危险的
  • static_cast和reinterpret_cast的区别主要在于多重继承,比如
[cpp] view plaincopyprint?
  1. <span style="font-size: 18px;">classA { public: int m_a;};
  2. classB { public: int m_b;};
  3. classC : public A, public B {};</span>
classA { public: int m_a;};
classB { public: int m_b;};
classC : public A, public B {};

  那么对于以下代码:

[cpp] view plaincopyprint?
  1. <span style="font-size: 18px;">C c;
  2. printf("%p,%p, %p\r\n", &c,
  3. reinterpret_cast<B*>(&c),
  4. static_cast<B*>(&c)  );</span>
C c;
printf("%p,%p, %p\r\n", &c,             reinterpret_cast<B*>(&c),static_cast<B*>(&c)  );

  前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节,这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c里面有m_a, m_b,转换为B*指针后指到m_b处),而reinterpret_cast却不会做这一层转换。

四、dynamic_cast:

  • dynamic_cast运算符可以在执行期决定真正的类型。如果downcast是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果downcast不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。
  • 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
  • 进行向下类型转换时,必须是一个指向带有虚函数的类类型的指针。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表,只有定义了虚函数的类才有虚函数表。
  • 使用dynamic_cast要付出显著地运行开销和内存开销。

可以参考下面这个例子进行理解:

[cpp] view plaincopyprint?
  1. <span style="font-size: 18px;">Base b;
  2. 00291A8B  lea         ecx,[b]
  3. 00291A8E  call        Base::Base (291131h)
  4. Base* pb = NULL;
  5. 00291A93  mov         dword ptr [pb],0
  6. Derived d;
  7. 00291A9A  lea         ecx,[d]
  8. 00291A9D  call        Derived::Derived (2911C7h)
  9. Derived* pd = NULL;
  10. 00291AA2  mov         dword ptr [pd],0
  11. pb = &d;
  12. 00291AA9  lea         eax,[d]
  13. 00291AAC  mov         dword ptr [pb],eax
  14. pd = static_cast<Derived*>(pb);
  15. 00291AAF  mov         eax,dword ptr [pb]
  16. 00291AB2  mov         dword ptr [pd],eax
  17. pd = dynamic_cast<Derived*>(pb);
  18. 00291AB5  push        0
  19. 00291AB7  push        offset Derived `RTTI Type Descriptor' (29A018h)
  20. 00291ABC  push        offset Base `RTTI Type Descriptor' (29A000h)
  21. 00291AC1  push        0
  22. 00291AC3  mov         eax,dword ptr [pb]
  23. 00291AC6  push        eax
  24. 00291AC7  call        @ILT+640(___RTDynamicCast) (291285h)
  25. 00291ACC  add         esp,14h
  26. 00291ACF  mov         dword ptr [pd],eax
  27. </span>
Base b;
00291A8B  lea         ecx,[b]
00291A8E  call        Base::Base (291131h)
Base* pb = NULL;
00291A93  mov         dword ptr [pb],0  Derived d;
00291A9A  lea         ecx,[d]
00291A9D  call        Derived::Derived (2911C7h)
Derived* pd = NULL;
00291AA2  mov         dword ptr [pd],0  pb = &d;
00291AA9  lea         eax,[d]
00291AAC  mov         dword ptr [pb],eax
pd = static_cast<Derived*>(pb);
00291AAF  mov         eax,dword ptr [pb]
00291AB2  mov         dword ptr [pd],eax  pd = dynamic_cast<Derived*>(pb);
00291AB5  push        0
00291AB7  push        offset Derived `RTTI Type Descriptor' (29A018h)
00291ABC  push        offset Base `RTTI Type Descriptor' (29A000h)
00291AC1  push        0
00291AC3  mov         eax,dword ptr [pb]
00291AC6  push        eax
00291AC7  call        @ILT+640(___RTDynamicCast) (291285h)
00291ACC  add         esp,14h
00291ACF  mov         dword ptr [pd],eax

【转载】C++运算符之类型转换相关推荐

  1. # c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符...

    c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符 标签(空格分隔): c++ 前言 我在c++学习的过程中, 对这几个不太常见的运算符重载不太会写.出现了很 ...

  2. JavaScript3基础——运算符和类型转换

    JavaScript3基础--运算符和类型转换      JavaScript运算符     JavaScript运算符也称操作符.其作用是对目标数据进行运算操作. 基本数学运算符     + - * ...

  3. php学习笔记-php运算符,类型转换,打印输出语句相较于其他语言的特殊部分-day02

    php运算符,类型转换,打印输出语句相较于其他语言的特殊部分 php运算符 php的类型转换 php打印输出语句 php运算符 1.php运算符与其他高级语言相同的部分 算术运算符(+,-,*,/,% ...

  4. C# 编程入门第二课 注释变量,VS2019快捷键,String和string,命名规则,赋值运算符,+号作用占位符,转义字符算术运算符,类型转换

    C# 编程入门第二课 文章目录 C# 编程入门第二课 1. 注释 2 变量 3.VS2019快捷键 4. String和string 5. 命名规则 6. 赋值运算符,+号作用 7. 占位符 8.转义 ...

  5. [转载] Python基础之类型转换与算术运算符

    参考链接: Python中的运算符函数| 1 一.注释 1.注释:对程序进行标注和说明,增加程序的可读性.程序运行的时候会自动忽略注释. 2.单行注释:使用#的形式.但是#的形式只能注释一行,如果有多 ...

  6. JAVA-常量、运算符、类型转换、Scanner

    01复习和常量: package GUIJIN_fuxihechangliang; /*** 复习:* 数据类型:* 基本数据类型:* 数值型:byte short int long* 浮点型:flo ...

  7. 前端JavaScript(1) --Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏...

    一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...

  8. python 全栈开发,Day50(Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏)...

    一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...

  9. ECMAScript5.1的运算符、类型转换总结

    一.运算符优先级 从高到低 运算符 说明 () 圆括号 . [] new(带参数列表) 字段访问.数组索引.new(带参数列表) () new(无参数列表) 函数调用,无参数列表 ++(后置递增) - ...

最新文章

  1. Swift 代码调试-善用XCode工具(UI调试,五种断点,预览UIImage...)
  2. Excel报表配置说明
  3. vtigercrm学习(二)
  4. JS 加强篇!推荐 10 个好用的 TypeScript 的开源项目 YYDS !
  5. 如何在不同摄像头里识别行人?多层相似度感知CNN网络解析
  6. 第六课:不要为金钱而工作
  7. python scapy sniff timeout_为什么我尝试使用scapy.sniff()函数获取此奇怪的输出,以尝试监听打开的网站的流量?...
  8. Django10:Ajax介绍/发送数据/SweetAlert
  9. 函数返回指针类型(strchr函数)
  10. matlab sunlink工具箱,FreeBSD handbook Unix Basics
  11. 配置php错误导入文件,php 导入文件(逻辑处理)
  12. Java数组快速排序
  13. 小学计算机键盘的初步认识教案,小学三年级信息技术--认识键盘教学设计(宋艳)[小编整理]...
  14. 关于MUI一个很实用的前端框架
  15. xftp7要继续使用此程序,您必须应用最新的更新,100%已解决.
  16. 美国计算机留学直博几年,美国读博士需要几年才能毕业?
  17. 从今以后我一个人唱悲伤情歌:伤感的QQ空间日志
  18. 无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll。尝试重新安装该程序以解决此问题。
  19. java switch的意思_java switch
  20. 【Linux】Linux运维命令汇总单词表

热门文章

  1. 拼多多黄峥一句话,阿里P8的我,越想越后怕
  2. 成年人不懂这些道理,会吃很多亏
  3. 这些人生经验与常识相反
  4. 线下实战—6月25号(深圳)
  5. 请设计输出实数的格式,包括:⑴一行输出一个实数;⑵一行内输出两个实数;⑶一行内输出三个实数。实数用quot;6.2fquot;格式输出。
  6. java ssm框架 缓存_SSM框架之Mybatis(7)延迟加载、缓存及注解
  7. 【面向对象】对象的本质
  8. 【软件工程】用于IS规划的SWOT方法
  9. 【Python】Matplotlib绘制可爱机器人
  10. (四)Go 语言编译流程简述