C++类型转换与RTTI应用

1、类型转换
a) dynamic_cast :使得能够在类层次结构中进行向上向下转换(向基类方向转换,is-a关系保证正确性),而不允许其他转换,该转换效率较低。

  • dynamic_cast要求类必须有虚函数;
  • 一种特殊的特性:把一个指针 dynamic_cast 成 void类型(或 const void或 volatile void* ),生成的指针将指向“原指针指向对象内存”的开始处

b) const_cast:只能用于去除同类对象的const,violate属性问题,常量变为非常量。
c) static_cast:用于强迫隐式转换,double转int,将非const转为const,以及各种数值转换(程序员保证安全性)。
d) reinterpret_cast:执行低级转型,实际动作(及结果)可能取决于编译器,表示其不可移植性,是危险的动作,比较少见,指针转int等等。

a)dynamic_cast 与static_cast区别:
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

2、运行阶段类型识别(RTTI)
作用:确定基类指针指向的是哪一类对象,以防止调用该类不存在的方法。
注:只适用于包含虚函数的类。

实现方式:
1、dynamic_cast:将基类指针a(指向某一基类或派生类对象)转换为某一派生类B指针。转换成功表明,该指针a指向的对象为该派生类B或该派生类的子类C的对象;失败则返回0(空指针)表明:指针a指向基类A的对象
2、type_id:返回指向对象类型的值。定义在type_info类中,接受两类参数:类名,对象名。
注:最好使用方式1,因为扩展性强。

例子:

//.h
Class A{
	virtual funa();
};
Class B :public A{
	virtual funa();
	virtual funb();
};
Class C :public B{
	virtual funa();
	func();
};

//.cpp
A* a1 = new A(); // a1->funb()运行失败。
A* a2 = new B(); // a2->funb()运行成功。
A* a3 = new C();
B* a;
C* x;

实现方式1dynamic_cast
if(a = dynamic_cast<B*>(a2)){ // 判断a2指向对象类型 
// 判断返回值,假如为空指针“0”,则表示false
// 基类指针指向基类对象时不能强转为派生类指针,因为基类没有派生类的特征
	a->funb(); //若a指向类A对象,则无此方法,会导致访问失败。
}
if(x = dynamic_cast<C*>(a3)){ // 判断a3指向对象类型
	x->func(); //若a3指向类A、B对象,则无此方法,会导致访问失败。
}

实现方式2:type_id
#include<type_info>
if(typeid(C) == typeid(*a3)){ // 两类型匹配则a3指向类型C对象。
	a3->func();
}

参考资料:C++ Primer Plus 15.4与15.5节

总结

1、基类指针指向基类对象时不能强转为派生类指针,因为基类不包含派生类的特征。
2、基类指针指向基类对象时不能调用派生类方法,可利用dynamic_cast判断指针指向的对象。
3、C++中类型转换方式如上所示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值