2

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++.

3
  • parashift.com/c++-faq-lite/inversion.html Commented Dec 19, 2013 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". Commented Dec 19, 2013 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
    Commented Dec 21, 2013 at 12:22

2 Answers 2

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;
}
5
  • 1
    dynamic_cast can be used if ancestor type has at least one virtual method, because it uses vtable, link
    – Renat
    Commented Dec 19, 2013 at 21:19
  • Thanks, you are correct. I tried to keep the example small. Will update
    – gvd
    Commented Dec 19, 2013 at 21:20
  • 1
    dynamic_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
    Commented Dec 19, 2013 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. Commented Dec 19, 2013 at 21:46
  • It crashes, but I think it needs a compiler flag for being able to determine a class at runtime.
    – CodeVomit
    Commented Dec 20, 2013 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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.