【转载】C++运算符之类型转换
该运算符用来修改类型的const或volatile属性。除了const或volatile修饰之外,type_id和expression的类型是一样的。
- 常量指针被转化成非常量指针,并且仍然指向原来的对象;
- 常量引用被转换成非常量引用,并且仍然指向原来的对象;
- 常量对象被转换成非常量对象。
- 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
- 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
- 把空指针转换成目标类型的空指针。
- 把任何类型的表达式转换成void类型。
- 操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。
- 所有映射中最危险的
- static_cast和reinterpret_cast的区别主要在于多重继承,比如
- <span style="font-size: 18px;">classA { public: int m_a;};
- classB { public: int m_b;};
- classC : public A, public B {};</span>
classA { public: int m_a;};
classB { public: int m_b;};
classC : public A, public B {};
那么对于以下代码:
- <span style="font-size: 18px;">C c;
- printf("%p,%p, %p\r\n", &c,
- reinterpret_cast<B*>(&c),
- 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要付出显著地运行开销和内存开销。
可以参考下面这个例子进行理解:
- <span style="font-size: 18px;">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
- </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++运算符之类型转换相关推荐
- # c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符...
c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符 标签(空格分隔): c++ 前言 我在c++学习的过程中, 对这几个不太常见的运算符重载不太会写.出现了很 ...
- JavaScript3基础——运算符和类型转换
JavaScript3基础--运算符和类型转换 JavaScript运算符 JavaScript运算符也称操作符.其作用是对目标数据进行运算操作. 基本数学运算符 + - * ...
- php学习笔记-php运算符,类型转换,打印输出语句相较于其他语言的特殊部分-day02
php运算符,类型转换,打印输出语句相较于其他语言的特殊部分 php运算符 php的类型转换 php打印输出语句 php运算符 1.php运算符与其他高级语言相同的部分 算术运算符(+,-,*,/,% ...
- C# 编程入门第二课 注释变量,VS2019快捷键,String和string,命名规则,赋值运算符,+号作用占位符,转义字符算术运算符,类型转换
C# 编程入门第二课 文章目录 C# 编程入门第二课 1. 注释 2 变量 3.VS2019快捷键 4. String和string 5. 命名规则 6. 赋值运算符,+号作用 7. 占位符 8.转义 ...
- [转载] Python基础之类型转换与算术运算符
参考链接: Python中的运算符函数| 1 一.注释 1.注释:对程序进行标注和说明,增加程序的可读性.程序运行的时候会自动忽略注释. 2.单行注释:使用#的形式.但是#的形式只能注释一行,如果有多 ...
- JAVA-常量、运算符、类型转换、Scanner
01复习和常量: package GUIJIN_fuxihechangliang; /*** 复习:* 数据类型:* 基本数据类型:* 数值型:byte short int long* 浮点型:flo ...
- 前端JavaScript(1) --Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏...
一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...
- python 全栈开发,Day50(Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏)...
一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...
- ECMAScript5.1的运算符、类型转换总结
一.运算符优先级 从高到低 运算符 说明 () 圆括号 . [] new(带参数列表) 字段访问.数组索引.new(带参数列表) () new(无参数列表) 函数调用,无参数列表 ++(后置递增) - ...
最新文章
- Swift 代码调试-善用XCode工具(UI调试,五种断点,预览UIImage...)
- Excel报表配置说明
- vtigercrm学习(二)
- JS 加强篇!推荐 10 个好用的 TypeScript 的开源项目 YYDS !
- 如何在不同摄像头里识别行人?多层相似度感知CNN网络解析
- 第六课:不要为金钱而工作
- python scapy sniff timeout_为什么我尝试使用scapy.sniff()函数获取此奇怪的输出,以尝试监听打开的网站的流量?...
- Django10:Ajax介绍/发送数据/SweetAlert
- 函数返回指针类型(strchr函数)
- matlab sunlink工具箱,FreeBSD handbook Unix Basics
- 配置php错误导入文件,php 导入文件(逻辑处理)
- Java数组快速排序
- 小学计算机键盘的初步认识教案,小学三年级信息技术--认识键盘教学设计(宋艳)[小编整理]...
- 关于MUI一个很实用的前端框架
- xftp7要继续使用此程序,您必须应用最新的更新,100%已解决.
- 美国计算机留学直博几年,美国读博士需要几年才能毕业?
- 从今以后我一个人唱悲伤情歌:伤感的QQ空间日志
- 无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll。尝试重新安装该程序以解决此问题。
- java switch的意思_java switch
- 【Linux】Linux运维命令汇总单词表