2010-05-05 115 views
0

這是我的代碼:如何檢查派生類中對象的類型名稱?

代碼
class Base { /* something */ }; 
class Derived : public Base { /* something */ }; 
vector<Base*> v; // somebody else initializes it, somewhere 
int counter = 0; 
for (vector<Base*>::iterator i=v.begin(); i!=v.end(); ++i) { 
    if (typeof(*i) == "Derived") { // this line is NOT correct 
    counter++; 
    } 
} 
cout << "Found " << counter << " derived classes"; 

一號線是不正確的。我應該如何正確書寫它?提前謝謝了!

回答

5

typeid的名稱是實現定義的,你不應該對它們做出假設。不過,你可以比較兩個typeid的。

if typeid(**i) == typeid(Derived) 

通常會被認爲是不好的設計(但如果目的只是寫一個不是很實用程序來算的衍生的實例,它只是罰款)。

注意,這也需要基地有虛表(虛函數和/或析構函數),因爲非多態類型只是沒有動態類型的typeid檢查(也就是,他們都成爲Base實例就typeid而言)。

如果你沒有任何虛擬功能,那麼你需要自己模擬它。例如,如果你喜歡字符串比較,並且不介意開銷,那麼在Base中添加一個字段,每個類型將在其構造函數中填寫並進行比較。否則,使用獨特整體識別每個亞型等

+0

謝謝,現在一切都很明確:) – yegor256 2010-05-05 15:41:45

+0

我發現這個鏈接:http://www.boost.org/doc/libs/1_42_0/libs/type_traits/doc/html/boost_typetraits/reference/is_same.html。看起來像這個庫可以幫助.. – yegor256 2010-05-05 16:51:22

+0

@Vincenzo:這隻在編譯時纔有效。在編譯時,向量中的所有靜態類型都是相同的。你需要一個運行時機制。 – UncleBens 2010-05-05 17:35:54

0

我認爲typeof僅適用於C#。

的SO發佈 「How to typeof in C++」 可能是使用的...

更新: This可能是使用:

typeof運算符,據我所知,是一個GCC 擴展。從GCC 3.2.3開始,它不再適用於模板對象 。 錯誤報告: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9459

版本的變化: http://www.gnu.org/software/gcc/gcc-3.2/changes.html

目前GCC似乎有一個非常 很難確定,即使在合法的情況下 的 模板函數的類型......

我認爲GCC支持__typeof__運營商。

正如其他人所說,我想你可以使用typeid作爲替代。

+0

感謝您的建議,但問題是我如何做比較。我不需要typeid信息。我需要能夠將它與一個字符串進行比較。謝謝 – yegor256 2010-05-05 15:33:41

0

看看typeid運營商。

一般來說,使用它是不好的主意。

+0

亞歷克斯,有什麼好的選擇呢?謝謝 – yegor256 2010-05-05 15:31:48

+0

使用dynamic_cast比較好,但無論如何,通常你不需要知道對象的確切類型。所有的邏輯都可以通過虛擬功能來實現。但是,有時您需要知道確切的類型,在這種情況下,您必須使用typeid。 – a1ex07 2010-05-05 16:04:52

5

使用的dynamic_cast:

if (dynamic_cast <Derived*>(*i)) { 
    counter++; 

對於這個工作,你需要給你的基類的至少一個虛擬功能 - 它確實需要一個虛析構函數無論如何。

0

您可以使用typeid(包括<typeinfo>):

if (typeid(**i) == typeid(Derived)) 

,或者您可以使用動態轉換:

if (dynamic_cast<Derived*>(*i) != 0) 

但兩者的代碼通常應該支持虛擬功能來避免被調用並被覆蓋以對每種類型執行適當的操作。

+0

你確定最後一點建議適用於此。爲什麼應該寫一個虛擬函數來模擬已經存在的相同RTTI(除了留下更少的錯誤空間外)? – UncleBens 2010-05-05 15:37:22

+0

@UncleBens:我如何確定我們所擁有的只是玩具示例代碼?但是我確信在絕大多數用例中,是的,我的最後一點建議是適用的。即使在玩具示例中,也可以爲虛擬'isDerived'函數與'count_if'一起使用。 – 2010-05-05 15:42:06

+0

感謝您的評論,康拉德!但是,我沒有基類中的任何虛函數。 – yegor256 2010-05-05 15:42:41

0

我想你想:

for (...) { 
    if (dynamic_cast<Derived*>(*i)) { 
    counter++; 
    } 
} 

的dynamic_cast <>試圖將基類指針轉換爲派生類指針。如果對象是派生類型(或其子類),則返回正確的指針。如果不是該派生類型,則返回'nil'來表示轉換不能成功完成。