30~C++ RTTI (runtime type Identification)

本文深入探讨了C++中的RTTI(运行阶段类型识别)特性,包括typeid与typeinfo操作符的使用,以及如何利用RTTI进行动态类型转换。通过实例代码展示了如何在运行时确定对象类型,并安全地进行多态继承中的类型转换。

RTTI 简介

R T T I是运行阶段类型识别(Runtime Type Identification)的简称。这是新添加到C++中的特性之一,
很多老式实现不支持。另一些实现可能需要RTTI开关的编译器设置。RTTI旨在为程序在运行阶段确定对象的类型提供一种标准方式。

RTTI只适用于包含虚函数的类!

1. typeid与typeinfo 操作符

操作符:typeid
通过typeid操作符可以获取一个类型或变量运行时类型信息,通过typeinfo类型对象提供给使用者,typeinfo::name()返回类型名字符串,而且typeinfo也支持“==”和“!=”运算符,判断类型相同或者不同


#include <iostream>
#include <typeinfo>
#include <cstring>
using namespace std;
class A { virtual void foo (void) {} };
class B : public A {
//	virtual void foo (void) {}
};
class C : public A {};
void bar (A const& a) {
//	if (! strcmp (typeid (a).name (), "1A"))
	if (typeid (a) == typeid (A))
		cout << "作为A的处理分支..." << endl;
	else
//	if (! strcmp (typeid (a).name (), "1B")) {
	if (typeid (a) == typeid (B)) {
		cout << "作为B的处理分支..." << endl;
		B const& b =
			static_cast<B const&> (a);
		// ...
	}
	else
//	if (! strcmp (typeid (a).name (), "1C")) {
	if (typeid (a) == typeid (C)) {
		cout << "作为C的处理分支..." << endl;
		C const& c =
			static_cast<C const&> (a);
		// ...
	}
}
int main (void) {
	int a;
	cout << typeid (a).name () << endl;
	double b;
	cout << typeid (b).name () << endl;
	unsigned int c;
	cout << typeid (c).name () << endl;
	char***** d;
	cout << typeid (d).name () << endl;
	int e[5];
	cout << typeid (e).name () << endl;
	int* f[5]; // 指针数组
	cout << typeid (f).name () << endl;
	int (*g)[5]; // 数组指针
	cout << typeid (g).name () << endl;
	int* (*h) (int*, int*);
	cout << typeid (h).name () << endl;
	B i;
	A* p = &i;
	cout << typeid (*p).name () << endl;
	A j;
	C k;
	bar (j);
	bar (i);
	bar (k);
	return 0;
}

2. RTTI应用:动态类型转换

如果存在多态继承,dynamic_cast在运行时检查转换源对象的实际类型是否与期望得到的目标类型一致,否则返回失败。



#include <iostream>
using namespace std;
class A {
	virtual void foo (void) {}
};
class B : public A {};
class C : public B {};
class D {};
int main (void) {
	B b;
	A* pa = &b;
	A& ra = b;
	cout << "pa = " << pa << endl;
	B* pb = dynamic_cast<B*> (pa);
	cout << "pb = " << pb << endl;
	C* pc = dynamic_cast<C*> (pa);
	cout << "pc = " << pc << endl;
	if (! pc) {
		cout << "类型转换失败!" << endl;
		// ...
	}
	try {
		C& rc = dynamic_cast<C&> (ra);
	}
	catch (exception& ex) {
		cout << "类型转换失败:" << ex.what()
			<< endl;
		// ...
	}
	D* pd = dynamic_cast<D*> (pa);
	cout << "pd = " << pd << endl;

	return 0;


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值