close

RTTI是什麼?做這些有什麼意義?
~~我想,很多programmer對這個既熟悉又充滿陌生的辭彙感到一知半解。
熟悉的地方是,每天都要用它。引擎裡有用到,就算引擎沒有,對於一個專業的物件導向程式設計師來說,
RTTI是不可或缺的,畢竟設計一個class就是在宣告一個型別(Type)。陌生的地方是,很多人都會用(因為有人已經寫好了,只要call function就好),但是卻不了解怎麼做,一個programmer怎麼可以對技術一知半解,這要怎麼生存。寫這邊文章的最主要目標就是分享我對RTTI研究的心得,希望也能夠帶給大家許多幫助,我會用連小學五年級都懂的話來告訴大家。

RTTI(Run-Time Type Information, or Run-Time Type Identification)
執行時期型態資訊(辨識)C++可以將基礎類別指向衍生類別,這通常發生在程式執行時,因此你並不知道這個基礎類別指向的物件型態是什麼,如此就必須在執行時期才可以做到取得物件資訊的,瞭解物件的資訊之後才能做正確的操作。那要怎麼做呢?

最簡單的方法就是使用
typeiddynamic_cast
這裡先簡單說明一下dynamic_cast。

dynamic_cast是C++的動態型別轉換機制,簡單來說就是在執行時期安全的將指標(pointer)或是參考(reference)轉換到衍生類別。首先會確認轉換目標與來源是否屬同一個類別階層,當轉換的是指標時,成功時回傳記憶體位址,失敗則回傳NULL,如果轉換的是參考,失敗則會丟出一個bad_cast

if (A * pA = dynamic_cast<A *>(pBase))
{
    //轉型成功
    pA->OK();
}

try
{
    A & rA = dynamic_cast<A &>(rBase);
    rA.OK();
}
catch(std::bad_cast)
{
    //轉型失敗
}

typeid就是產生指標或是參考所實際指向的物件的資訊結構
type_info
typeid表示式:
    typeid(exp);
exp的意思是類別的指標或是參考,或是其類別名稱。typeid傳回的是一個type_info的物件參考。

type_info:

class type_info {
public:
    virtual ~type_info();
    bool operator==(const type_info& rhs) const;
    bool operator!=(const type_info& rhs) const;
    int before(const type_info& rhs) const;
    const char* name() const;
    const char* raw_name() const;
};

你無法直接instance type_info這個類別,因為此類別只有一個私有的複製建構子,你也無法用assignment來建立,因為assignment operator也是私有的。你只能透過typeid這個function來建立。

==, !=運算子顧名思義就是判斷該type_info是否和其他的type_info相同。

name這個member function回傳一個人類可以看的懂的字串來顯示該指標指向之類別名稱。

raw_name說的就是一個原始的名字,也就是在記憶體裡存放的資料,這表示我們一般人是看不懂的(因該只有受過專業的訓練才看的懂吧)。但是它比name快,因為name就是把這些資料轉換成我們看的懂的文字。不過一般人是不會用raw_name的。

用法很簡單,請看下面。

if (typeid(pBase) == typeid(A))
{
    //pBase指向的是A
    A * pA = dynamic_cast<A *>(pBase);
    pA->OK();
}

if (typeid(pA) == typeid(pB))
{
    //兩個pointer是相同的class
}

cout << typeid(pA).name();

以上就是RTTI的基本知識,另外一點要提的就是
要使用RTTI,你必須inlcude <typeinfo>這個header file
在VC++的專案設定裡C/C++ --> Language --> Enable Run-Time Type Info設定為
Yes (/GR)

就先寫到這裡吧
下一回在跟大家更深入的談RTTI


全站熱搜
創作者介紹
創作者 kgsprogrammer 的頭像
kgsprogrammer

太陽系後援會

SnakeEater 發表在 痞客邦 留言(0) 人氣()