1. 程式人生 > >C++異常處理(二)=>RTTI

C++異常處理(二)=>RTTI

/*對於RTTI(執行階段型別識別)主要包含dynamic_cast,typeid,type_info*/

1.dynamic_cast

對於指標轉換,從派生類轉換成基類指標將會返回物件地址,如果轉換錯誤將會返回NULL

對於引用轉換,轉換錯誤將會引發bad_cast異常,在標頭檔案<typeinfo>

2.typeid

typeid()返回一個type_info物件引用

3.type_info

獲取類資訊,可以利用name()方法來獲取類名(並非一定),也可以進行比較

//rtti.h
#ifndef _RTTI_H_
#define _RTTI_H_
#include<iostream>
#include<string>
/*對於RTTI(執行階段型別識別)主要包含dynamic_cast,typeid,type_info*/
using namespace std;
class A
{
private:
	int a1;
	double a2;
public:
	A(const int &t1, const double &t2) :a1(t1), a2(t2){}
	virtual ~A(){}
	virtual void show()const{ cout << "class A: a1=" << a1 << ",a2=" << a2 << endl; }
	virtual void set(const int &t1, const double &t2){ a1 = t1; a2 = t2; }
};
class B :public A
{
private:
	string b;
public:
	B(const int &t1, const double &t2, const string &str) :A(t1, t2), b(str){}
	virtual ~B(){}
	virtual void show()const{ cout << "class B: b=" << b << endl; }
	virtual void set(const string &str){ b = str; }
};
class C :public B
{
private:
	char ch;
public:
	C(const int &t1, const double &t2, const string &str, const char &c) :B(t1, t2, str), ch(c){}
	~C(){}
	void show()const{ cout << "class C: ch=" << ch<< endl; }
	virtual void set(const char &c){ ch = c; }
};

#endif //_RTTI_H_


//main.cpp

//#include<iostream>
#include<cstdlib>
#include<ctime>
#include"windows.h"
#include"rtti.h"
#include<typeinfo>
const int TEST = 6;
using namespace std;
A* select();
int main()
{
	srand(time(0));
	B *bpt;
	A *apt;
	for (int i = 0; i < TEST; i++)
	{
		apt = select();
		cout << "Now, I'm a " << typeid(*apt).name() << " class\n";
		//typeid(*apt)返回一個type_info物件引用
		if (bpt = dynamic_cast<B *>(apt))
		/*派生類可以向基類轉換並返回地址,轉換失敗返回NULL(對於指標)
	對於引用將不會返回NULL,將會返回bad_cast異常(在typeinfo標頭檔案宣告)*/
			bpt->show();
		if (typeid(*apt) == typeid(C))
			cout << "It really a C class\n";
		cout << "***********Test Over************\n";
	}
  system("pause");
  return 0;
}

A* select()
{
	A *temp;
	switch (rand() % 3)
	{
	case 0:temp = new A(rand() % 50, double(rand() % 20));
		break;
	case 1:temp = new B(rand() % 50, double(rand() % 20),"I'm B class");
		break;
	case 2:temp = new C(rand() % 50, double(rand() % 20), "I'm B class", 'C');
		break;
	default:temp = nullptr;
	}
	return temp;
}

程式執行結果如下: