RTTI(Run-Time Type Information,通過運行時類型信息)程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。
c++有三個支持RTTI的元素
1)如果可能的話,dynamic_cast運算符將使用一個指向基類的指針來生成一個指向派生類的指針,否則,該運算符返回0 ——空指針。
dynamic_cast < Type *> (pt);
通常,如果指向對象(*pt)的類型為Type或者是從Type直接或間接派生而來的類型,則上述表達式將指針pt轉換為Type類型的指針。
否則,結果為0,即空指針。
2) typeid 運算符返回i一個指出對象的類型的值。
typeid對象使得能夠確定兩個對象是否是同種類型,它與sizeof有些相像,可以接受兩種參數:
類名
結果為對象的表達式
它返回一個對type_info對象的引用。
3)type_info結構存儲了有關特定類型的信息。
type_info是一個在頭文件typeinfo中定義的一個類,重載了== 和 !=運算符
#include
#include
#include
#include
using std::cout;
class Grand
{
private:
int hold;
public:
Grand(int h = 0) : hold(h) {}
virtual void Speak() const { cout << I am a grand class!
;}
int Value() const { return hold; }
};
class Superb : public Grand
{
public:
Superb(int h = 0) : Grand(h) {}
void Speak() const { cout << I am a superb class!!
; }
virtual void Say() const
{
cout << I hold the superb value of << Value() << !
;
}
};
class Magnificent : public Superb
{
private:
char ch;
public:
Magnificent( int h = 0, char c = 'A') : Superb(h), ch(c) {}
void Speak() const { cout << I am a magnificent class!!!
; }
void Say() const { cout << I hold the character << ch <<
and the integer << Value() << !
; }
};
Grand* GetOne();
int main()
{
std::srand(std::time(0));
Grand* pg;
Superb* ps;
for (int i = 0; i < 5; i++)
{
pg = GetOne();
pg->Speak();
if (ps = dynamic_cast(pg))
ps->Say();
if (typeid(Magnificent) == typeid(*pg))
cout<
運行結果:
C++的RTTI提供了幾個最基本的功能:
1、安全的downcast,當你使用dynamic_cast動態從基類指針轉換成子類指針的時候,RTTI能保證安全的轉換,如果類型不符則拋出一個bad_cast異常。
2、動態獲取一個對象的類名稱。你可以使用typeid獲得一個type_info對象,這個對象保存了這個類型的最基本信息,比如名稱。
3、在繼承樹上遍歷,使用typeid獲得的type_info對象提供一個before方法,可以用於查找這個類型的基類。