青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 74, 文章 - 0, 評論 - 26, 引用 - 0
數(shù)據(jù)加載中……

如何在運行時確定對象類型(RTTI) 轉(zhuǎn)

RTTI 是“Runtime Type Information”的縮寫,意思是:運行時類型信息。它提供了運行時確定對象類型的方法。本文將簡略介紹 RTTI 的一些背景知識、描述 RTTI 的概念,并通過具體例子和代碼介紹什么時候使用以及如何使用 RTTI;本文還將詳細描述兩個重要的 RTTI 運算符的使用方法,它們是 typeid 和 dynamic_cast。
    其實,RTTI 在C++中并不是什么新的東西,它早在十多年以前就已經(jīng)出現(xiàn)了。但是大多數(shù)開發(fā)人員,包括許多高層次的C++程序員對它并不怎么熟悉,更不用說使用 RTTI 來設計和編寫應用程序了。
    一些面向?qū)ο髮<以趥鞑プ约旱脑O計理念時,大多都主張在設計和開發(fā)中明智地使用虛擬成員函數(shù),而不用 RTTI 機制。但是,在很多情況下,虛擬函數(shù)無法克服本身的局限。每每涉及到處理異類容器和根基類層次(如 MFC)時,不可避免要對對象類型進行動態(tài)判斷,也就是動態(tài)類型的偵測。如何確定對象的動態(tài)類型呢?答案是使用內(nèi)建的 RTTI 中的運算符:typeid 和 dynamic_cast。
    首先讓我們來設計一個類層次,假設我們創(chuàng)建了某個處理文件的抽象基類。它聲明下列純虛擬函數(shù):open()、close()、read()和 write():
class File
{
public:
virtual int open(const string & filename)=0;
virtual int close(const string & filename)=0;
//
virtual ~File()=0; // 記住添加純虛擬析構函數(shù)(dtor)
};
現(xiàn)在從 File 類派生的類要實現(xiàn)基類的純虛擬函數(shù),同時還要提供一些其他的操作。假設派生類為 DiskFile,除了實現(xiàn)基類的純虛擬函數(shù)外,還要實現(xiàn)自己的flush()和defragment()操作:
class DiskFile: public File
{
public:
int open(const string & filename);

// 實現(xiàn)其他的純虛擬函數(shù)
......

// 自己的專有操作
virtual int flush();
virtual int defragment();
};
接著,又從 DiskFile 類派生兩個類,假設為 TextFile 和 MediaFile。前者針對文本文件,后者針對音頻和視頻文件:
class TextFile: public DiskFile
{
// ......
int sort_by_words();
};

class MediaFile: public DiskFile
{
//......
};
我們之所以要創(chuàng)建這樣的類層次,是因為這樣做以后可以創(chuàng)建多態(tài)對象,如:
File *pfile; // *pfile的靜態(tài)類型是 File
if(some_condition)
pfile = new TextFile; // 動態(tài)類型是 TextFile
else
pfile = new DiskFile; // 動態(tài)類型是 DiskFile
    假設你正在開發(fā)一個基于圖形用戶界面(GUI)的文件管理器,每個文件都可以以圖標方式顯示。當鼠標移到圖標上并單擊右鍵時,文件管理器打開一個菜單,每 個文件除了共同的菜單項,不同的文件類型還有不同的菜單項。如:共同的菜單項有“打開”“拷貝”、和“粘貼”,此外,還有一些針對特殊文件的專門操作。比 如,文本文件會有“編輯”操作,而多媒體文件則會有“播放”菜單。為了使用 RTTI 來動態(tài)定制菜單,文件管理器必須偵測每個文件的動態(tài)類型。利用 運算符 typeid 可以獲取與某個對象關聯(lián)的運行時類型信息。typeid 有一個參數(shù),傳遞對象或類型名。因此,為了確定 x 的動態(tài)類型是不是Y,可以用表達式:typeid(x) == typeid(Y)實現(xiàn):
#include <typeinfo> // typeid 需要的頭文件
void menu::build(const File * pfile)
{
if (typeid(*pfile)==typeid(TextFile))
{
add_option("edit");
}
else if (typeid(*pfile)==typeid(MediaFile))
{
add_option("play");
}
}
    使用 typeid 要注意一個問題,那就是某些編譯器(如 Visual C++)默認狀態(tài)是禁用 RTTI 的,目的是消除性能上的開銷。如果你的程序確實使用了 RTTI,一定要記住在編譯前啟用 RTTI。使用 typeid 可能產(chǎn)生一些將來的維護問題。假設你決定擴展上述的類層次,從MediaFile 派生另一個叫 LocalizeMedia 的類,用這個類表示帶有不同語言說明文字的媒體文件。但 LocalizeMedia 本質(zhì)上還是個 MediaFile 類型的文件。因此,當用戶在該類文件圖標上單擊右鍵時,文件管理器必須提供一個“播放”菜單??上? build()成員函數(shù)會調(diào)用失敗,原因是你沒有檢查這種特定的文件類型。為了解決這個問題,你必須象下面這樣對 build() 打補?。?
void menu::build(const File * pfile)
{

//......

else if (typeid(*pfile)==typeid(LocalizedMedia))
{
add_option("play");
}
}
    唉,這種做法真是顯得太業(yè)余了,以后每次添加新的類,毫無疑問都必須打類似的補丁。顯然,這不是一個理想的解決方案。這個時候我們就要用到 dynamic_cast,這個運算符用于多態(tài)編程中保證在運行時發(fā)生正確的轉(zhuǎn)換(即編譯器無法驗證是否發(fā)生正確的轉(zhuǎn)換)。用它來確定某個對象是 MediaFile 對象還是它的派生類對象。dynamic_cast 常用于從多態(tài)編程基類指針向派生類指針的向下類型轉(zhuǎn)換。它有兩個參數(shù):一個是類型名;另一個是多態(tài)對象的指針或引用。其功能是在運行時將對象強制轉(zhuǎn)換為目標類型并返回布爾型結果。也就是說,如果該函數(shù)成功地并且是動態(tài)的將 *pfile 強制轉(zhuǎn)換為 MediaFile,那么 pfile的動態(tài)類型是 MediaFile 或者是它的派生類。否則,pfile 則為其它的類型:
void menu::build(const File * pfile)
{
if (dynamic_cast <MediaFile *> (pfile))
{
// pfile 是 MediaFile 或者是MediaFile的派生類 LocalizedMedia
add_option("play");
}
else if (dynamic_cast <TextFile*> (pfile))
{
// pfile 是 TextFile 是TextFile的派生類
add_option("edit");
}
}
    細細想一下,雖然使用 dynamic_cast 確實很好地解決了我們的問題,但也需要我們付出代價,那就是與 typeid 相比,dynamic_cast 不是一個常量時間的操作。為了確定是否能完成強制類型轉(zhuǎn)換,dynamic_cast`必須在運行時進行一些轉(zhuǎn)換細節(jié)操作。因此在使用 dynamic_cast 操作時,應該權衡對性能的影響。

posted on 2008-11-19 14:59 井泉 閱讀(984) 評論(1)  編輯 收藏 引用 所屬分類: C++

評論

# re: 如何在運行時確定對象類型(RTTI) 轉(zhuǎn)  回復  更多評論   

很好,學習了
2012-03-28 15:55 | kelvn
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            最新国产拍偷乱拍精品| 久久精品男女| 亚洲欧美日韩一区在线| 伊人久久婷婷色综合98网| 欧美电影在线播放| 久久蜜桃香蕉精品一区二区三区| 亚洲国产精品尤物yw在线观看| 亚洲国产精品久久| 国内揄拍国内精品久久| 欧美电影在线观看| 久久久久久噜噜噜久久久精品 | 久久成人资源| 久久精品亚洲热| 亚洲中午字幕| 欧美在线精品一区| 久久综合九色综合久99| 欧美高清视频免费观看| 欧美日韩少妇| 韩日成人av| 正在播放欧美视频| 久久夜色精品国产噜噜av| 亚洲第一页在线| 亚洲欧美一区二区三区久久| 亚洲黄色尤物视频| 亚洲午夜成aⅴ人片| 久久亚洲精选| 国产日韩在线看| 亚洲精品一区二区在线| 午夜在线a亚洲v天堂网2018| 美女国产精品| 亚洲欧美精品伊人久久| 免费成人黄色av| 欧美天堂亚洲电影院在线观看| 国产毛片久久| 亚洲综合色网站| 亚洲福利视频一区| 久久久噜噜噜久久中文字幕色伊伊 | 久久国产夜色精品鲁鲁99| 久久综合亚州| 亚洲综合三区| 国产精品福利影院| 99riav久久精品riav| 亚洲精品人人| 欧美日韩国产大片| 久久亚洲精选| 欧美夜福利tv在线| 国产综合视频| 免费视频一区二区三区在线观看| 欧美亚洲午夜视频在线观看| 国产精品自在线| 久久免费黄色| 欧美在线视频导航| 欧美自拍偷拍| 国产精品手机视频| 久久久999精品免费| 免费成人在线视频网站| 亚洲二区在线视频| 日韩一级欧洲| 一本色道久久综合亚洲精品小说| 午夜国产精品视频| 亚洲私人影吧| 欧美日韩视频专区在线播放| 欧美黑人一区二区三区| 国产无一区二区| 亚洲欧美精品一区| …久久精品99久久香蕉国产 | 欧美日韩国产在线| 老司机免费视频久久| 国产精品久久久久久一区二区三区 | 久久成人久久爱| 亚洲欧美久久久久一区二区三区| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲色图制服丝袜| 欧美激情久久久久久| 亚洲承认在线| 亚洲天堂偷拍| 久久福利视频导航| 欧美日韩一区二区在线播放| 欧美粗暴jizz性欧美20| 亚洲第一精品福利| 美女任你摸久久| 91久久久久久久久| 妖精视频成人观看www| 欧美日韩国产一级片| 亚洲理论在线| 欧美一区二区三区在线视频| 国产精品人成在线观看免费| 香港成人在线视频| 欧美黄色网络| 午夜精品久久久久久久蜜桃app | 亚洲主播在线观看| 久久久www成人免费无遮挡大片 | 久久久一区二区| 亚洲电影免费| 国产精品久久久久久久久久久久久久 | 欧美性jizz18性欧美| 亚洲一区网站| 欧美国内亚洲| 久久久久久综合网天天| 日韩午夜剧场| 午夜精品美女自拍福到在线 | 亚洲大胆视频| 久久精品一区二区国产| 亚洲与欧洲av电影| 国产综合婷婷| 国产日韩欧美在线| 国产欧美一区二区精品性| 欧美日产在线观看| 欧美国产日韩一区二区在线观看| 久久精品国产久精国产思思| 亚洲欧美日韩电影| 亚洲午夜激情网页| 久久国产高清| 免费观看成人| 欧美日韩午夜剧场| 国产精品一区二区你懂得| 欧美网站大全在线观看| 国产精品美女主播| 伊人久久亚洲影院| 一本色道久久综合亚洲精品按摩 | 亚洲精品网址在线观看| 一区二区三区国产精华| 欧美亚洲免费高清在线观看| 久久黄色级2电影| 亚洲激情偷拍| 亚洲影院一区| 蜜桃av一区二区在线观看| 欧美日韩精品久久久| 国产一区亚洲| 亚洲欧美一区在线| 欧美电影免费观看高清完整版| 亚洲人成7777| 久久精品国产免费观看| 欧美日韩成人一区二区| 亚洲丁香婷深爱综合| 久久激情网站| 香蕉成人啪国产精品视频综合网| 久久精品国产成人| 亚洲视频在线一区| 欧美日本高清一区| 在线观看欧美激情| 久久久夜色精品亚洲| 亚洲在线一区二区| 国产精品免费一区二区三区观看 | 另类图片综合电影| 在线成人www免费观看视频| 久久不射中文字幕| 欧美中文字幕在线| 尤物在线精品| 欧美激情性爽国产精品17p| 久久精品国产一区二区电影| 国产日韩亚洲欧美| 老色鬼精品视频在线观看播放| 欧美一区精品| 亚洲国产一二三| 日韩视频亚洲视频| 国产欧美一区二区精品性色| 欧美一区二区三区免费大片| 午夜精品福利视频| 伊人久久大香线蕉综合热线| 亚洲国产精品久久人人爱蜜臀| 久久综合久久久久88| 一区二区国产日产| 欧美一级日韩一级| 日韩一级在线观看| 午夜欧美电影在线观看| 亚洲九九九在线观看| 亚洲一区二区三区中文字幕在线| 国产一区二区毛片| 亚洲免费观看视频| 国产在线不卡精品| 一区二区三区蜜桃网| 精品av久久久久电影| 夜夜狂射影院欧美极品| 黑人一区二区三区四区五区| 国产精品一区二区黑丝| 亚洲三级国产| 91久久精品www人人做人人爽 | 久久频这里精品99香蕉| 欧美日韩一区二区在线视频| 亚洲日本欧美天堂| 亚洲欧洲另类国产综合| 欧美性理论片在线观看片免费| 欧美成年人视频网站| 影音先锋中文字幕一区| 午夜精品剧场| 久久精品毛片| 依依成人综合视频| 牛牛影视久久网| 欧美色视频一区| 亚洲私人影院在线观看| 欧美另类极品videosbest最新版本 | 亚洲已满18点击进入久久| 日韩视频免费| 欧美日韩成人免费| 亚洲特黄一级片| 久久免费精品视频| 亚洲精品在线观| 国产精品一区在线观看| 欧美在线精品免播放器视频|