C++ 中RTTI的使用方法詳解
C++ 中RTTI的使用方法詳解
RTTI是運(yùn)行階段類型識別(Runtime Type Identification)的簡稱。這是新添加到c++中的特性之一,很多老式實現(xiàn)不支持。另一些實現(xiàn)可能包含開關(guān)RTTI的編譯器設(shè)置。RTTI旨在為程序在運(yùn)行階段確定對象類型提供一種標(biāo)準(zhǔn)方式。很多類庫已經(jīng)成為其父類對象提供了實現(xiàn)這種方式的功能。但由于c++內(nèi)部并不支持,因此各個廠商的機(jī)制通?;ゲ患嫒荨?chuàng)建一種RTTI語言標(biāo)準(zhǔn)將使得未來的庫能夠彼此兼容。
c++有3個支持RTTI的元素
如果可能的話,dynamic_cast 運(yùn)算符將使用一個指向基類的指針來生成一個指向派生類的指針;否則,該運(yùn)算符返回0——空指針
typied運(yùn)算符返回一個指出對象的類型的值
type_info結(jié)構(gòu)存儲了有關(guān)特定類型的信息
假設(shè)我們有下面的類層次結(jié)構(gòu):
class Grand{ //has virtual methods}; class Super:public Grand {...} class Magnificent : public Superb{...}
假設(shè)有下面的指針:
Grand *pg = new Grand ; Grand *ps = new Superd; Grand *pm = new Manificent;
1、dynamic_cast
我們來看一下dynamic_cast的語法,該語法用法如下,其中pg指向一個對象
Superb pm = dynamic_cast< Superb > (pg) ;
這樣 指針 pg 如果可以安全的轉(zhuǎn)換為Superb * 則返回對象地址,否則返回一個空指針。
示例:
// test1002.cpp : 定義控制臺應(yīng)用程序的入口點。 // #include "stdafx.h" #include <cstdlib> #include <ctime> #include<iostream> 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 \n"; } virtual 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 ! \n"; } virtual void Say() const { cout << "I hold the superb value of " << Value() << "! \n"; } }; 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 !!!! \n"; } void Say() const { cout << "I hold the character " << ch << " and the integer " << Value() <<"! \n"; } }; Grand * GetOne(); int main() { std::srand(static_cast<unsigned int>(std::time(0))); Grand * pg; Superb * ps; for (int i = 0; i < 5; i++) { pg = GetOne(); pg->Speak(); if (ps = dynamic_cast<Superb *>(pg)) { ps->Say(); } } system("pause"); return 0; } Grand * GetOne() { Grand * p = new Grand(); switch (std::rand() % 3) { delete p; case 0:p = new Grand(std::rand() % 100); break; case 1:p = new Superb(std::rand() % 100); break; case 2:p = new Magnificent(std::rand() % 100, std::rand() % 26); break; } return p; } 運(yùn)行結(jié)果: I am a superb class ! I hold the superb value of 3! I am a magnificent class !!!! I hold the character and the integer 5! I am a grand class I am a grand class I am a magnificent class !!!! I hold the character and the integer 87! 請按任意鍵繼續(xù). . .
2、typied運(yùn)算符合type_info 類
typied 運(yùn)算符能夠確定兩個對象是否為同類型。他接收兩種參數(shù):1、類名、2、結(jié)果為對象的表達(dá)式
typied運(yùn)算符返回的是一個type_info對象的引用,type_info在頭文件typeinfo(以前是typeinfo.h)的文件中定義。type_info類重載了== 和!=運(yùn)算符,以便可以使用這些運(yùn)算符來對類型進(jìn)行比較。
示例: typeid(Manificnent) == typeid(*pg) 這個表達(dá)式結(jié)果為 bool值
如果pg是一個空指針,程序?qū)⒁l(fā)bad_typied異常。該異常類型是從exception類中派生而來的。是在typeinfo中聲明的。
type_info類的實現(xiàn)隨廠商而異,但包含一個name()成員,該函數(shù)返回一個隨實現(xiàn)而異的字符串:通常是類的名字。
示例
// test1002.cpp : 定義控制臺應(yīng)用程序的入口點。 // #include "stdafx.h" #include <cstdlib> #include <ctime> #include<iostream> #include <typeinfo> 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 \n"; } virtual 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 ! \n"; } virtual void Say() const { cout << "I hold the superb value of " << Value() << "! \n"; } }; 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 !!!! \n"; } void Say() const { cout << "I hold the character " << ch << " and the integer " << Value() <<"! \n"; } }; Grand * GetOne(); int main() { std::srand(static_cast<unsigned int>(std::time(0))); Grand * pg; Superb * ps; for (int i = 0; i < 5; i++) { pg = GetOne(); cout << "Now Process type " << typeid (*pg).name() << ". \n"; //顯示 pg->Speak(); if (ps = dynamic_cast<Superb *>(pg)) { ps->Say(); } } system("pause"); return 0; } Grand * GetOne() { Grand * p = new Grand(); switch (std::rand() % 3) { delete p; case 0:p = new Grand(std::rand() % 100); break; case 1:p = new Superb(std::rand() % 100); break; case 2:p = new Magnificent(std::rand() % 100, std::rand() % 26); break; } return p; } 運(yùn)行結(jié)果: Now Process type class Superb. I am a superb class ! I hold the superb value of 86! Now Process type class Grand. I am a grand class Now Process type class Superb. I am a superb class ! I hold the superb value of 48! Now Process type class Grand. I am a grand class Now Process type class Magnificent. I am a magnificent class !!!! I hold the character and the integer 75! 請按任意鍵繼續(xù). . .
上述代碼添加了一句 typied(*pg).name() 用于輸出類型信息,一般輸出為類名。
如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
C語言實現(xiàn)linux網(wǎng)卡連接檢測的方法
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)linux網(wǎng)卡連接檢測的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06DHCP:解析開發(fā)板上動態(tài)獲取ip的2種實現(xiàn)方法詳解
本篇文章是對開發(fā)板上動態(tài)獲取ip的2種實現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Visual?C++?6.0添加一個對話框的實現(xiàn)步驟
VC6.0是微軟公司推出的一款集成開發(fā)環(huán)境,本文主要介紹了Visual?C++?6.0添加一個對話框的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下2024-06-06C語言實現(xiàn)學(xué)生成績管理系統(tǒng)課程設(shè)計
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)學(xué)生成績管理系統(tǒng)課程設(shè)計,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07通過c語言調(diào)用系統(tǒng)curl動態(tài)庫的示例詳解
這篇文章中我們將通過一個簡單的示例來講解如何在Ubuntu系統(tǒng)中通過C語言調(diào)用動態(tài)庫(共享庫)的方法,我們將使用libcurl庫,這是一個基于客戶端的URL傳輸庫,廣泛用于各種程序和應(yīng)用中以訪問網(wǎng)頁和服務(wù)器數(shù)據(jù),需要的朋友可以參考下2024-03-03