77范文网 - 专业文章范例文档资料分享平台

关于C++中的类型转换操作符(3)

来源:网络收集 时间:2019-06-11 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

| +CBase X--------+ |\\

| | int x | | 4 bytes

| +---------------+ |/

| |

| +CBase Y--------+ |

| | int y,*py | |

| +---------------+ |

+--------------------------+

*第69行和70行的可以将父类指针用static_cast强制转换成子类指针,但是两个无关的类的指针之间却不能转换。

*第74行中使用reinterpret_cast将子类指针强制转换赋给父类指针后,却没有像static_cast那样将父类指针位置调整以指向正确的对象位置,这样导致虽然两者值是一样的,但是父指针所指向的内容却不是父对象了。

*第76行之后使用void将子类转换成父类再转回子类,却无法使用了。

因为任何指针可以被转换到void*,而void*可以被向后转换到任何指针(对于static_cast<> 和 reinterpret_cast<>转换都可以这样做),如果没有小心处理的话错误可能发生。一旦我们已经转换指针为void*,我们就不能轻易将其转换回原类所以使用void转换的时候一定要小心。在上面的例子中,从一个void* 返回CDerived*的唯一方法是将其转换为CBaseY*然后再转换为CDerived*。但是如果我们不能确定它是CBaseY* 还是 CDerived*,这时我们不得不用dynamic_cast<> 或typeid[2](dynamic_cast<>需要类成为多态,即包括“虚”函数,并因此而不能成为void*)。

[其它]

dynamic_cast<>,从另一方面来说,可以防止一个泛型CBaseY* 被转换到CDerived*。

四、const_cast

=====================

用法:const_cast (expression)

[功能]

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

[描述]

const_cast剥离一个对象的const属性,允许对常量进行修改。

常量指针被转化成非常量指针,并且仍然指向原来的对象;

常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

Voiatile和const类似。参见后面的例子可以了解更多信息。

[举例]

给出的源代码如下:

1 #include

2 using std::cout;

3 using std::endl; 4

5 class CTest

6 {

7 public:

8 CTest(int i){m_val = i;cout<<\

9 ~CTest(){cout<<\

10 void SelfAdd(){m_val++;};

11 int m_val;

12 }; 13

14 int main(int argc, char *argv[])

15 {

16 const int ic = 100;

17 //int cc = const_cast(ic);//编译错误

18 int cc = const_cast(ic);

19 cout<

20 //const_cast(&ic)=200;//编译错误,从类型 ‘const int*’ 到类型 ‘int&’ 中的 const_cast 无效

21 const_cast(ic)=200;

22 cout<

23 cout<<*(&ic)<

24 //int *pc = ⁣//编译错误,从类型 ‘const int*’ 到类型 ‘int*’ 的转换无效

25 const int *pc=⁣

26 //const_cast(pc)=200;//编译错误,从类型 ‘const int**’ 到类型 ‘int*’ 中的 const_cast 无效

27 const_cast(ic)=200;

28 //printf(\

29 cout<

30 //int *ppc = const_cast(ic);//编译错误

31 int *ppc = const_cast(&ic);

32 *ppc = 300;

33 cout<

35 const CTest test(1000);

36 CTest test2(1050);

37 //test = test2;//编译错误,无法给常量赋值

38 const_cast(test)= test2;

39 cout<

40 }

这里,结果输出参见每行代码相应的注释。根据结果可知:凡是对结构体或类进行这个转换,都是成功的,但对char,short等基本类型的转换,通过直接打印变量显示其值都是不成功的,但是通过指针却能显示出修改之后的值。

通过对代码进行反汇编,可知,虽然本身我们没使用优化,但系统还是对ic这个const进行了预编译般的替换,将它替换成“64h”(十六进制的64就是十进制的100),这肯定不是一般用户想要的结果,如果它不是一个C++的规范,应该算是个C++的bug吧。

[其他]

注意,

(1)操作对象

const_cast操作的对象必须是pointer, reference, nor a pointer-to-data-member type,如下代码是错误的:

const int a = 5;

int aa = const_cast(a);

而使用引用的方式,如下却是正确的:

const int a = 5;

int aa = const_cast(a);

(2)可能的误解

可能上面的描述误解的地方,根据参考资料中的一个评论,说:const_cast只能修改变量的常引用的const属性,和变量的常指针的const属性,还有对象的const属性。要想改变常量本身的值是不可能的,也就是说,你改变的是引用的const属性,而不是常量本身的const属性。估计 const int ic = 100; 定义的时候就已经将这个基础类型对象放入常量符号表里面了,永远不会改变它的值。

五、其它

=====================

做为一个对前面所说的四种类型转换操作符的补充,对它们之间的区别大致进行说明一下,如下:

1,static_cast和dynamic_cast的对比:

1)static_cast在编译期间发现错误。

对于基本类型,

它不允许将一种类型的指针指向另一种类型,所以如下代码是错误的:

float f = 12.3;

float* pf = &f;

int* pn = static_cast(pf);//编译错误,指向的类型是无关的,不能将指针指向无关的类型

对于复合类型(例如类,

它允许转换子对象地址赋值给父指针,也允许转换父对象地址赋值给子指针,但是不允许两个无关的类之间的转换,所以如下是错误的:

CBaseX *pX = &cx;

CBaseY *pY = &cy;

pX = static_cast(pY);//编译错误,从类型 ‘CBaseY*’ 到类型 ‘CBaseX*’ 中的 static_cast 无效。

2)dynamic_cast在运行期间发生错误,它只允许它允许转换子对象地址赋值给父指针,其它情况都返回空。

例如:

B *pb = new B;

D *pd = dynamic_cast(pb); //pd is NULL

delete pb;

2,static_cast,dynamic_cast和reinterpret_cast之间的对比:

1)static_cast和dynamic_cast可以执行指针到指针的转换,或实例本身到实例本身的转换,但不能在实例和指针之间转换。static_cast只能提供编译时的类型安全,而dynamic_cast可以提供运行时类型安全。举个例子:

class a;class b:a;class c。

上面个类a是基类,b继承a,c和a,b没有关系。假设有一个函数void function(a&a);现在有一个对象是b的实例b,一个c的实例c。function(static_cast(b)可以通过而function(static(c))不能通过编译,因为在编译的时候编译器已经知道c和a的类型不符,因此static_cast可以保证安全。

2)reinterpret_cast可以转换任意一个32bit整数,包括所有的指针和整数。可以把任何整数转成指针,也可以把任何指针转成整数,以及把指针转化为任意类型的指针,威力最为强大!但不能将非32bit的实例转成指针。总之,只要是32bit的东东,怎么转都行!对于刚刚说的例子,下面我们骗一下编译器,先把c转成类型a

b& ref_b = reinterpret_castc;

这样,function(static_cast(ref_b))就通过了!因为从编译器的角度来看,在编译时并不能知道ref_b实际上是c!而function(dynamic_cast(ref_b))编译时也能过,但在运行时就失败了,因为dynamic_cast在运行时检查了ref_b的实际类型,这样怎么也骗不过去了。

在应用多态编程时,当我们无法确定传过来的对象的实际类型时使用dynamic_cast,如果能保证对象的实际类型,用static_cast就可以了。至于reinterpret_cast很象c语言那样的暴力转换。

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库关于C++中的类型转换操作符(3)在线全文阅读。

关于C++中的类型转换操作符(3).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/656469.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: