I have a pointer to an object, I want to know if that object is either of type of a given class or of type that is a subclass of the given class in C++.
            Asked
            
        
        
            Active
            
        
            Viewed 1,240 times
        
    2
            
            
        - 
                    http://www.parashift.com/c++-faq-lite/inversion.html – Iłya Bursov Dec 19 '13 at 21:15
 - 
                    Do you want to detect each of those things separately? As in "If it's the class, do this, and if it's a subclass, do this". Or do you just want to detect either of them? As in "If it's the class or a subclass, do this". – Joseph Mansfield Dec 19 '13 at 21:15
 - 
                    To be pedantic (and if you do C++, you *should* be pedantic), the pointer *always* points to an object of its pointee type. However, that object may be a *subject* of a more-derived object. – Kerrek SB Dec 21 '13 at 12:22
 
2 Answers
5
            
            
        Use dynamic_cast:
class A {
public:
    virtual ~A() = default;
};
class B : public A {    
};
B * obj = new B();
auto obj2 = dynamic_cast<A*>(obj);
if (obj2 != nullptr) {
    std::cout << "B is an A" << std::endl;
}
        gvd
        
- 1,823
 - 13
 - 18
 
- 
                    1dynamic_cast can be used if ancestor type has at least one virtual method, because it uses vtable, [link](http://stackoverflow.com/questions/4227328/faq-why-does-dynamic-cast-only-work-if-a-class-has-at-least-1-virtual-method) – Renat Dec 19 '13 at 21:19
 - 
                    
 - 
                    1dynamic_cast will even allow you to cast across a hierarchy in C++. So given, BaseA, BaseB, and Derived which derives from both (using multiplie inheritance), then a pointer to BaseA which actually points to a Derived object can be successfully cast to a BaseB using dynamic_cast. – YoungJohn Dec 19 '13 at 21:28
 - 
                    1`std::type_info::before` relates to an arbitrary collation order on types. It doesn't tell you whether one is a base of the other. – Steve Jessop Dec 19 '13 at 21:46
 - 
                    It crashes, but I think it needs a compiler flag for being able to determine a class at runtime. – CodeVomit Dec 20 '13 at 14:41
 
2
            
            
        The pointer you start with must have a type. Let's say that type is T*. Let's say the "given class" is G. I think (although I may be wrong) that it's the complete type of the object that you want to know about, not the relation between the types T and G.
If T is a class type with at least one virtual function, then you can do the test you want on a pointer ptr like this:
if (dynamic_cast<G*>(ptr)) {
    // then the complete type of your object is either G or a subclass
} else {
    // it isn't
}
If T is not a class type, or if it doesn't have a virtual function, then what you want to do is not possible. You'll have to find a more useful static type for the pointer.
If all you want to know is whether G is "either a base of or the same as" T then you don't need dynamic_cast or for there to be a virtual function. You just need std::is_base_of.
        Steve Jessop
        
- 273,490
 - 39
 - 460
 - 699