2012-07-15 62 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。