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++.
-
parashift.com/c++-faq-lite/inversion.html– Iłya BursovCommented 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".– Joseph MansfieldCommented 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 SBCommented Dec 21, 2013 at 12:22
2 Answers
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;
}
-
1
-
Thanks, you are correct. I tried to keep the example small. Will update– gvdCommented Dec 19, 2013 at 21:20
-
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. 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. Commented Dec 20, 2013 at 14:41
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
.