2013-04-09 100 views
14

可以說我們有一個類層次結構。在底部我們有Base和Derived頂部。 如何確定對象類,即使它被轉換爲基類指針。如何在C++運行時確定實際的對象類型;

Base* b = new Derived(): 

typeid(b).name(); // i want this to tell me that this is actually derived not base object 

除了手動實現字符串字段或這樣的虛擬get函數之外,還有其他任何方法嗎?

PS:我講的編譯器無關的解決方案

+3

這是可能的,正如答案中所解釋的那樣,但這幾乎總是一件錯誤的事情。你想在這裏做什麼? – 2013-04-09 09:28:02

+0

沒什麼,只是爲了爭辯的目的:) – user1079475 2013-04-09 09:40:23

+1

更多面嚮應用程序的版本:http://stackoverflow.com/questions/351845/finding-the-type-of-an-object-in-c ||沒有提及繼承的更通用的版本:http://stackoverflow.com/questions/11310898/how-do-i-get-the-type-of-a-variable – 2015-06-18 15:11:15

回答

26

確保基類至少有一個虛方法,包括<typeinfo>並使用您當前的代碼只是一個額外的非關聯化,typeid(*b).name()


順帶注意, typeid通話是在C一處++,你可以取消引用具有良好定義的行爲一空指針,這意味着它可以拋出一個異常:

C++ 11§ 5.2.8/2
「如果通過施加一元*操作者一個 指針得到的glvalue表達和指針是空指針值(4.10)時,typeid表達拋出std::bad_typeid異常(18.7.3) 。 」

+4

這是一個好主意,讓析構函數爲「at至少有一個虛擬方法「 – 2013-04-09 09:25:18

8

如果你想要做的是找到如果b實際上指向Derived,只需使用dynamic_cast()

if (dynamic_cast<Derived*>(b)) { ... } 

dynamic_cast返回一個空指針,如果對象的實際運行時類型指向b不是Derived(或從Derived派生的類)。與std::type_infoname()成員不同,這是編譯器不變的。

請注意,這僅適用於Base至少有一個虛擬成員函數。無論如何它應該是這樣的,因爲你通過一個基指針來操作從它派生的類型,所以它應該有一個虛擬析構函數。

+0

但情況是,我不想隨時隨地添加新課程。 – user1079475 2013-04-09 09:39:24

相關問題