RTTI 和 类型转换运算符

RTTI(Runtime Type Identification),译为运行阶段类型识别。是新添加到C++的特性。

1、用途。

对于一个类层次结构:其中的类都是从一个基类派生而来,则可以让基类指针指向其中任何一个类的对象。

则可以调用函数:在处理一些信息后,选择一个类,并创建这种类型的对象,之后返回它的地址。

该地址可以被基类指针引用。然而,我们并不知道基类指针指向的是什么对象。

在回答这个问题前,先考虑为何要知道类型——若仅仅是希望调用类方法的正确版本,则只要该类层次结构中所有成员都拥有虚函数,则并不需要知道真正的类型。

而相反,派生对象也可能包含不是继承而来的方法,在这种情况下,只有某些类型的对象可以使用该方法——无论是出于调试或是向跟踪生成的对象的类型。对于后两种,RTTI提供解决方法。

2、工作原理。

C++有三个支持RTTI的元素。

1、如果可能的话,dynamic_cast 将使用一个指向基类的指针来生成一个指向派生类的指针,否则将返回0。

2、typeid运算符返回一个指出对象的类型的值。

3、type_info结构存储了有关特定类型的信息。

 

详细介绍:

1、dynamic_cast:

它是最常见的RTTI组件,它回答“是否可以安全地将对象的地址赋给特定类型的指针”的问题。

使用如下:

class Grand{};
class Superb: public Grand{};
class Magnificent:public Superb{};

dynamic_cast<Type *>(pt);
Super * pm = dynamic_cast<Superb *>(bg);

其中,若pt指针指向的类型为Type或从Type派生而来的类型,则dynamic_cast将pt的类型转换为Type* 类型的指针,否则结果为0,返回空指针。

 

2、typeid运算符和type_info类

typeid运算符使得能够确定两个对象是否为同种类型,于sizeof相似,不过能接受两种参数。

   1、类名;2、结果为对象的表达式。

同时,typeid返回一个对type_info对象的引用,type_info是在头文件typeinfo中定义的一个类,它重载了==和!=运算符,以便可以用这些运算符对类型进行比较。

typeid(Magnificent) == typeid(*pg)

其中,若pg指向一个空指针,将引发bad_typeid异常——它在typeinfo声明,由exception派生。

同时,type_info类的实现随厂商而异,但包含一个name()成员——它可以显示类名。

 

类型转换运算符

比起C语言的强制转换,C++采取了更为严格地限制转换的措施,并添加了4个类型转换运算符。

1、dynamic_cast;

2、const_cast;

3、static_cast;

4、reinterpret_cast;

dynamic_cast已在上文提到——它实现类层次结构的向上转换。语法为:

dynamic_cast<type_name>(expression)

const_cast运算符用于执行只有一种用途的类型的转换。即改变值为const或volatile,语法与dynamic_cast相同。

注意其中的volatile:volatile是一个特征修饰符(type specifier).volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。

High bar;
const High * pbar = &bar;

High * pb = const_cast<High *>(pbar);
const Low * pl = const_cast<const Low*>(pbar); //invalid

在上述的代码中,第一条尝试将const High* 类型转换为High *类型,这样就能通过pb指针修改它的值。

而第二条语句却尝试将const High * 转换为const Low *,不符合要求。

 

3、static_cast

static_cast<type_name>(expression)

中,它仅允许能从type_name到expreesion所属类型或从expression所属类型到type_name的隐式转换。

例:若A类由B类派生,则A、B类可相互转换,而与之无关的C类则不能转换。

 

4、reinterpret_cast运算符用于天生危险的类型转换——它不允许删除const,但会执行其他操作。

语法:

reinterpret_cast<type_name>(expression)

使用如下:

struct dat{short a;short b};
long value = 0xA224B118;
dat*pt = reinterpret_cast<dat*>(&value);
cout<<hex<<pd->a;

long类型拥有的字节数为32,地址与两个short相当,因此转换成立。它将0xA224B118的值在底层转换为了两个int类型。

要注意,它也不能执行所有的类型转换,如将指针类型转换为更小的整型或浮点数。也不能完成函数指针与数据指针的转换。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值