数据类型转换.docx
- 文档编号:18578971
- 上传时间:2023-08-19
- 格式:DOCX
- 页数:23
- 大小:185.83KB
数据类型转换.docx
《数据类型转换.docx》由会员分享,可在线阅读,更多相关《数据类型转换.docx(23页珍藏版)》请在冰点文库上搜索。
数据类型转换
数据类型转换
一、隐式类型转换
1)简单数据类型
(1)算术运算
转换为最宽的数据类型
eg:
[cpp]viewplaincopy
#include
usingstd:
:
cout;
usingstd:
:
endl;
intmain(intargc,char*argv[])
{
intival=3;
doubledval=3.14159;
cout< return0; } 其运行结果: 6.14159 intmain(intargc,char*argv[]) { 010D17D0pushebp 010D17D1movebp,esp 010D17D3subesp,0DCh 010D17D9pushebx 010D17DApushesi 010D17DBpushedi 010D17DCleaedi,[ebp-0DCh] 010D17E2movecx,37h 010D17E7moveax,0CCCCCCCCh 010D17ECrepstosdwordptres: [edi] intival=3; 010D17EEmovdwordptr[ival],3 doubledval=3.14159; 010D17F5movsdxmm0,mmwordptr[__real@400921f9f01b866e(010D6B30h)] 010D17FDmovsdmmwordptr[dval],xmm0 cout< 010D1802movesi,esp 010D1804pushoffsetstd: : endl : char_traits 010D1809cvtsi2sdxmm0,dwordptr[ival] 010D180Eaddsdxmm0,mmwordptr[dval] 010D1813movedi,esp 010D1815subesp,8 010D1818movsdmmwordptr[esp],xmm0 010D181Dmovecx,dwordptr[_imp_? cout@std@@3V? $basic_ostream@DU? $char_traits@D@std@@@1@A(010D90A8h)] 010D1823calldwordptr[__imp_std: : basic_ostream : char_traits : operator<<(010D90A0h)] 010D1829cmpedi,esp 010D182Bcall__RTC_CheckEsp(010D111Dh) 010D1830movecx,eax 010D1832calldwordptr[__imp_std: : basic_ostream : char_traits : operator<<(010D90A4h)] 010D1838cmpesi,esp 010D183Acall__RTC_CheckEsp(010D111Dh) return0; 010D183Fxoreax,eax } 010D1841popedi } 010D1842popesi 010D1843popebx 010D1844addesp,0DCh 010D184Acmpebp,esp 010D184Ccall__RTC_CheckEsp(010D111Dh) 010D1851movesp,ebp 010D1853popebp 010D1854ret (2)赋值 转换为被赋值对象的类型,但不会改变赋值对象的数据类型。 eg: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; intmain(intargc,char*argv[]) { intival=4; doubledval=3.14159; ival=dval;//double->int cout< cout< return0; } 其运行结果: 3.14159 3 注意: 数据类型窄化转换时,注意数据溢出及丢失。 (3)函数传参 当实参与形参数据类型不同时,转换为形参数据类型。 eg: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; doublesquare(doubledval); intmain(intargc,char*argv[]) { cout< return0; } doublesquare(doubledval) { returndval*dval; } 其运行结果: 25 (4)函数返回 当返回类型与表达式类型不同时,转换为返回类型。 eg: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; doubledifference(intival1,intival2); intmain(intargc,char*argv[]) { intival1=2; intival2=3; cout< return0; } doubledifference(intival1,intival2) { returnival1-ival2;//返回值被提升为double类型 } 其运行结果: -1 2)类类型 (1)单参数构造函数 (2)赋值操作符 (3)类型转换操作符 eg: [cpp]viewplaincopy //implicitconversionofclasses: #include usingstd: : cout; usingstd: : endl; classA{}; classB{ public: //conversionfromA(constructor) B(constA&x) { cout<<"ConversionfromA(constructor)"< } //conversionfromA(assignment) B&operator=(constA&x) { cout<<"ConversionfromA(assignment)"< return*this; } //conversiontoA(type-castoperator) operatorA() { cout<<"ConversiontoA(type-castoperator)"< returnA(); } }; intmain(intargc,char*argv[]) { Afoo; Bbar=foo;//callsconstructor bar=foo;//callsassignment foo=bar;//callstype-castoperator return0; } 其运行结果: ConversionfromA(constructor) ConversionfromA(assignment) ConversiontoA(type-castoperator) 二、显示类型转换 1)C风格 dst=(T)src eg: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; intmain(intargc,char*argv[]) { intival; doubledval=3.14159; ival=(int)dval;//double->int cout< cout< return0; } 其运行结果: 3.14159 3 2)函数风格 dst=T(src) eg: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; intmain(intargc,char*argv[]) { intival; doubledval=3.14159; ival=int(dval);//double->int cout< cout< return0; } 其运行结果: 3.14159 3 3) (1)static_cast a、类层次结构中基类和派生类之间指针或者引用的转换。 up-casting(把派生类的指针或引用转换成基类的指针或者引用表示)是安全的;down-casting(把基类指针或引用转换成子类的指针或者引用)是不安全的。 b、基本数据类型之间的转换 c、把空指针转换成目标类型的空指针(nullpointer) d、把任何类型的表达式转换成void类型 注意: 不能转换掉表达式的const、volitale或者__unaligned属性。 eg1: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; classDummy { doublei,j; }; classAddition { intx,y; public: Addition(inta,intb){x=a;y=b;} intresult(){returnx+y;} }; intmain(intargc,char*argv[]) { Dummyd; Addition*padd; padd=(Addition*)&d; cout< return0; } 其运行结果: -1717986920 不做类型检查,转换没有安全性 eg2: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; classDummy { doublei,j; }; classAddition { intx,y; public: Addition(inta,intb){x=a;y=b;} intresult(){returnx+y;} }; intmain(intargc,char*argv[]) { Dummyd; Addition*padd; padd=static_cast cout< return0; } (2)dynamic_cast 转换类型与表达式类型相同,必须同时是类的指针、类的引用或void*.用于类的上行、下行及交叉转换。 一般情况下,dynamic_cast用于具有多态性的类(即有虚函数的类)的类型转换。 a、上行转换时,其与static_cast效果相同; b、下行转换时,其具有类型转换的功能,比static_cast更安全; c、交叉转换时,其转换成空指针,而static_cast则不允许转换。 注意: 不能转换掉表达式的const、volitale或者__unaligned属性。 eg: [cpp]viewplaincopy //dynamic_cast #include #include usingstd: : cout; usingstd: : endl; usingstd: : exception; classBase{virtualvoiddummy(){}}; classDerived: publicBase{inta;}; intmain(intargc,char*argv[]) { try{ Base*pba=newDerived; Base*pbb=newBase; Derived*pd; pd=dynamic_cast if(pd==0)cout<<"Nullpointeronfirsttype-cast.\n"; pd=dynamic_cast if(pd==0)cout<<"Nullpointeronsecondtype-cast.\n"; } catch(exception&e){cout<<"Exception: "< return0; } 其运行结果: Nullpointeronsecondtype-cast. (3)reinterpret_cast 转换一个指针为其他类型的指针,也允许将一个指针转换为整数类型,反之亦然。 这个操作符能够在非相关的类型之间进行转换。 操作结果只是简单的从一个指针到别的指针的值的二进制拷贝,在类型之间指向的内容不做任何类型的检查和转换。 这是一个强制转换。 使用时有很大的风险,慎用之。 注意: 不能转换掉表达式的const、volitale或者__unaligned属性。 eg1: [cpp]viewplaincopy //expre_nterpret_cast_Operator.cpp //compilewith: /EHsc #include usingstd: : cout; usingstd: : endl; //Returnsahashcodebasedonanaddress unsignedshortHash(void*p) { unsignedintval=reinterpret_cast return(unsignedshort)(val^(val>>16)); } intmain(intargc,char*argv[]) { inta[20]; for(inti=0;i<20;i++) cout< } eg2: [cpp]viewplaincopy #include structFoo{}; structBar{}; intmain() { Foo*f=newFoo; Bar*b1=f; Bar*b2=static_cast Bar*b3=dynamic_cast Bar*b4=const_cast Bar*b5=reinterpret_cast return0; } 1>------已启动全部重新生成: 项目: test,配置: DebugWin32------ 1>main.cpp 1>f: \workspace\test\test\main.cpp(10): errorC2440: “初始化”: 无法从“Foo*”转换为“Bar*” 1>f: \workspace\test\test\main.cpp(10): note: 与指向的类型无关;转换要求reinterpret_cast、C样式转换或函数样式转换 1>f: \workspace\test\test\main.cpp(11): errorC2440: “static_cast”: 无法从“Foo*”转换为“Bar*” 1>f: \workspace\test\test\main.cpp(11): note: 与指向的类型无关;转换要求reinterpret_cast、C样式转换或函数样式转换 1>f: \workspace\test\test\main.cpp(12): errorC2683: “dynamic_cast”: “Foo”不是多态类型 1>f: \workspace\test\test\main.cpp(3): note: 参见“Foo”的声明 1>f: \workspace\test\test\main.cpp(13): errorC2440: “const_cast”: 无法从“Foo*”转换为“Bar*” 1>f: \workspace\test\test\main.cpp(13): note: 与指向的类型无关;转换要求reinterpret_cast、C样式转换或函数样式转换 ==========全部重新生成: 成功0个,失败1个,跳过0个========== (4)const_cast 修改类型的const或volatile属性 a、常量指针被转化成非常量指针,转换后指针指向原来的变量(即转换后的指针地址不变) eg1: [cpp]viewplaincopy //const_cast #include usingstd: : cout; usingstd: : endl; voidprint(char*str) { cout< } intmain(intargc,char*argv[]) { constchar*c="sampletext"; print(const_cast return0; } 其运行结果: sampletext eg2: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; classA { public: A() { m_iNum=0; } intm_iNum; }; intmain(intargc,char*argv[]) { //1、指针指向类 constA*pca1=newA; A*pa2=const_cast(pca1);//常量对象转换为非常量对象 pa2->m_iNum=200; //转换后指针指向原来的对象 cout< //2、指针指向基本类型 constintica=100; int*ia=const_cast *ia=200; cout<<*ia<<""< return0; } 其运行结果: 200200 200100 b、常量引用转为非常量引用 eg: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; classA { public: A() { m_iNum=1; } intm_iNum; }; intmain(intargc,char*argv[]) { Aa0; constA&a1=a0; Aa2=const_cast(a1);//常量引用转为非常量引用 a2.m_iNum=200; cout< cout< cout< return0; } 其运行结果: 1 1 200 c、常量对象(或基本类型)不可以被转换成非常量对象(或基本类型) eg: [cpp]viewplaincopy #include usingstd: : cout; usingstd: : endl; classA { public: A() { m_iNum=1; } intm_iNum; }; intmain(intar
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据类型 转换
![提示](https://static.bingdoc.com/images/bang_tan.gif)