2010-11-11 64 views
4

假設我們有三個類A,B和C.B從A派生而C從B派生。現在我們有一個指向A類對象的指針。由於多態性實際上可以指向所有三個類的實例。C++:是類的實例後裔

用typeid()我可以檢查指針實際引用的是什麼類型。但我試圖確定它是否指向B類的任何後代。也就是說,我正在尋找某種IsDescendantOf(unkownclass,baseclass)函數。在C++中有這樣做的原因嗎?

+0

不是一個確切的重複,但確切的情況進行了討論:http://stackoverflow.com/questions/1760365/possible-to-use-typeid - 確定 - 親子關係 – KevenK 2010-11-11 22:37:35

+4

如果您正確使用多態性,則很少需要'dynamic_cast ()'。你爲什麼需要這樣做? – 2010-11-11 22:37:43

回答

11

使用dynamic_cast。它在失敗時返回NULL:

B* pb = dynamic_cast<B*>(pa); 

您可能會感興趣的對象爲MSDN article

+0

示例測試:http://codepad.org/VQKbClBu – 2010-11-11 22:42:28

1

您可以通過dynamic_cast<TargetType*>(ptr)投射一個物體,然後檢查結果是否爲空(不能投射 - 不是後代)。

3

您也可以在編譯時使用模板元編程來測試它。它甚至可以工作,如果有問題的類沒有任何虛擬功能,其中dynamic_cast不會。

template <typename D, typename B> 
class is_derived_from { 
    class No { }; 
    class Yes { No no[2]; }; 

    static Yes Test(B*); 
    static No Test(...); 
public: 
    enum { inherits = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) }; 
    static bool is_derived() { return inherits; } 
}; 

我認爲這是來自優秀的GoTW系列之一。

+2

這隻有在指針所包含的類型在編譯時已知的情況下才有效。如果它在那裏是已知的,那麼應該使用['boost :: type_traits :: is_base_of'](http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits改爲/reference/is_base_of.html)。 – 2010-11-11 22:44:17

+0

這個問題在編譯時是否真的知道,或者它是否需要運行時,這個問題並不十分清楚。儘管使用boost而不是DIY解決方案是一個好的方面。 – Flexo 2010-11-11 22:46:30

0

使用std::is_base_of<type_traits>static_assert檢查在編譯時