2012-07-15 64 views
4

我有一個指向多態類型的指針,p。我也有一個type_info在同一個層次結構中的某個類,tiC++:使用typeinfo測試類繼承

如果我只比較typeid(*p) == ti,那麼我可以在運行時測試指針是否指向該類的直接實例。

是否有類似的方式來使用C++的RTTI來測試*p是否繼承了該類的

回答

2

單靠標準C++沒有辦法做到這一點。如果您使用的是具有Itanium C++ ABI 的實現,你可以儘管做到這一點,例如:

#include <iostream> 
#include <typeinfo> 
#include <cxxabi.h> 
#include <memory> 

class base { 
protected: 
    base() { 
    } 
public: 
    static bool check(const std::type_info& p) { 
    // Find the real type_info for single inheritance non virtual 
    const __cxxabiv1::__si_class_type_info* test = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&p); 
    return test ? typeid(base) == *test->__base_type : false; 
    } 

    virtual ~base() {} 
}; 

class der : public base { 
}; 

class foo {}; 

int main() { 
    der d; 
    foo f; 

    std::cout << base::check(typeid(d)) << "\n"; 
    std::cout << base::check(typeid(f)) << "\n"; 
} 

下面這個工作,因爲該類型有一個單一的,非virtuallly繼承的基礎。你可以支持更多的案例,儘管謹慎和類似dynamic_casts

儘管在某些情況下這是可能的,但我認爲你正在解決錯誤的問題 - 基於std::map的解決方案更具可移植性,避免依賴這樣的實現細節。

容易混淆的名字命名,這是一個令人驚訝的大編譯/建築列表,而不是隻是安騰

+0

我不,唉。 (我甚至沒有STL)。我認爲這將是答案,但無法找到任何明確的說法。哦,那麼,自定義RTTI,那麼... – 2012-07-15 12:04:24

+0

@DavidGiven - 這可能是你的實現有一個類似的ABI。 – Flexo 2012-07-15 12:06:30

1

是的,您可以使用dynamic_cast<>。如果您嘗試投射到Base*,它會執行運行時檢查,以查看您的課程是否確實是從Base(或直接是基地)衍生而來。如果失敗,dynamic_cast<>返回nullptr。例如:

struct Base { 
    virtual ~Base() {} 
}; 

struct AnotherBase { 
    virtual ~Base() {} 
}; 

struct Derived : Base {}; 


Base * basePtr = new Base(); 
Base * derivedPtr = new Derived(); 
AnotherBase * anotherBasePtr = new Base(); 

// is derivedPtr a pointer to a class derived from AnotherBase ? 
AnotherBase* test2 = dynamic_cast<AnotherBase*>(derivedPtr); // test2 == nullptr 

// is basePtr a pointer to a class derived from Derived ? 
Derived * test3 = dynamic_cast<Derived*>(basePtr); // test3 == nullptr 

側節點:

  • 如果dynamic_cast<>被用於轉換指針,它返回要麼nullptr或轉換後的指針。

  • 但當dynamic_cast<>是用來轉換引用它拋出一個異常失敗的情況下

  • 運行時檢查dynamic_cast<>只適用於多態類型。如果您的Base不包含任何虛函數(=非多態),將不可能安全地將Base*轉換爲Derived*

+0

不幸的是'dynamic_cast <>'只有在我知道類在_compile time_時纔有效。我不知道:我所有的都是類的'type_info'。我實際上並不需要投射指針,只是確定指向的對象是否繼承自我擁有'type_info'的類。 – 2012-07-15 11:32:02

+0

@DavidGiven我誤解了你的問題。所以不,你不能。但是你可以創建一個map 讓你做你想做的事。告訴我,如果你有興趣,我會發佈一個詳細的答案。 – 2012-07-15 11:47:26

+0

沒關係,謝謝。我已經有了一個自定義RTTI的計劃來做到這一點,但想要檢查我是否真的需要它。 – 2012-07-15 12:05:27

0

十分感謝柔印。我一直在研究C++ ABI。工作一小時後,我有了這個演示:http://pastebin.com/j7DYY5ej。在某些情況下,這是一個檢查繼承的代碼。我爲這些類型實現了運算符==,!=,<,>,< =,>> =。我打算改進這種類型方程式並將其用於我的項目中。 請注意,我在Linux下使用了G ++ 4.8。