Check if class is derived from a specific class (compile, runtime both answers available)
I have some remarks on the proposed compile-time x runtime solutions. In addition to when they are evaluated, is_base_of
and dynamic_cast
have different requirements and their answers can be different.
(1) First of all (as pointed out by others) to use dynamic_cast
, base and derived classes must be polymorphic (must have at least one virtual
method). is_base_of
doesn't require the types to be polymorphic.
(2) The operands of is_base_of
are both types whereas dynamic_cast
needs a type (inside < >
) and an object (inside ( )
).
(3) dynamic_cast
and is_base_of
can give different answers (or one can compile while the other doesn't) depending on the type of inheritance (public
vs protected
or private
). For instance consider:
struct B { virtual ~B() {} }; // polymorphic, so it can be used in a dynamic_cast
struct D1 : public B {}; // polymorphic by (public) inheritance
struct D2 : private B {}; // polymorphic by (private) inheritance
D1 d1;
D2 d2;
We have
static_assert(std::is_base_of<B, D1>::value, "");
static_assert(std::is_base_of<B, D2>::value, "");
assert(dynamic_cast<B*>(&d1));
assert(!dynamic_cast<B*>(&d2)); // Notice the negation.
Actually the last line yields a compiler error in GCC (error: 'B' is an inaccessible base of 'D2'
). VS2010 does compile it (yielding just a warning similar to GCC's error message).
(4) The requirements on the classes being polymorphic can be relaxed through an exception handling trick. Consider:
struct B { }; // not polymorphic
struct D1 : public B {}; // not polymorphic
struct D2 : private B {}; // not polymorphic
D1 d1;
D2 d2;
template <typename B, typename D>
const B* is_unambiguous_public_base_of(const D* obj) {
try {
throw obj;
}
catch (const B* pb) {
return pb;
}
catch (...) {
}
return nullptr;
}
Then we have
static_assert(std::is_base_of<B, D1>::value, "");
static_assert(std::is_base_of<B, D2>::value, "");
assert((is_unambiguous_public_base_of<B>(&d1)));
assert(!(is_unambiguous_public_base_of<B>(&d2))); // Notice the negation.
It's worth mentionning that is_unambiguous_public_base_of
is far slower than dynamic_cast
and (this became more obvious after the renaming mentioned in the update below) always returns a nullptr
for downcasts:
B* b1 = &d1;
assert(dynamic_cast<D1*>(b1)); // Requires D1 and B to be polymorphic.
assert(!(is_unambiguous_public_base_of<D1>(b1))); // Notice the negation.
A bit outdated reference on this trick is available in the following links:
Part 1, Part 2 and code
Disclaimer: the implementation of is_unambiguous_public_base_of
above is just a draft to make the point and it doesn't handle const
and volatile
qualifications properly.
Update: In a previous version of this post is_unambiguous_public_base_of
was named my_dynamic_cast
and this was a source of confusion. So I renamed it to a more meaningful name. (Thanks to Jan Herrmann.)
How do I check if an object's type is a particular subclass in C++?
You really shouldn't. If your program needs to know what class an object is, that usually indicates a design flaw. See if you can get the behavior you want using virtual functions. Also, more information about what you are trying to do would help.
I am assuming you have a situation like this:
class Base;
class A : public Base {...};
class B : public Base {...};
void foo(Base *p)
{
if(/* p is A */) /* do X */
else /* do Y */
}
If this is what you have, then try to do something like this:
class Base
{
virtual void bar() = 0;
};
class A : public Base
{
void bar() {/* do X */}
};
class B : public Base
{
void bar() {/* do Y */}
};
void foo(Base *p)
{
p->bar();
}
Edit: Since the debate about this answer still goes on after so many years, I thought I should throw in some references. If you have a pointer or reference to a base class, and your code needs to know the derived class of the object, then it violates Liskov substitution principle. Uncle Bob calls this an "anathema to Object Oriented Design".
Check if a Class Object is subclass of another Class Object in Java
You want this method:
boolean isList = List.class.isAssignableFrom(myClass);
where in general, List
(above) should be replaced with superclass
and myClass
should be replaced with subclass
From the JavaDoc:
Determines if the class or interface represented by this
Class
object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specifiedClass
parameter. It returnstrue
if so; otherwise it returnsfalse
. If thisClass
object represents a primitive type, this method returnstrue
if the specifiedClass
parameter is exactly thisClass
object; otherwise it returnsfalse
.
Reference:
Class.isAssignableFrom(Class)
Related:
a) Check if an Object is an instance of a Class or Interface (including subclasses) you know at compile time:
boolean isInstance = someObject instanceof SomeTypeOrInterface;
Example:
assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
b) Check if an Object is an instance of a Class or Interface (including subclasses) you only know at runtime:
Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);
Example:
public boolean checkForType(Object candidate, Class<?> type){
return type.isInstance(candidate);
}
How to test if one java class extends another at runtime?
Are you looking for:
Super.class.isAssignableFrom(Sub.class)
Check in compile time if someClass.class is derived from a anotherClass.class?
In code:
anotherClass.class.isAssignableFrom( someClass.class );
If you want to also check that the other class is a real class (and not an interface) add in a call to isInterface()
:
!anotherClass.class.isInterface() && anotherClass.class.isAssignableFrom( someClass.class );
Example:
System.out.println( Number.class.isAssignableFrom( Integer.class )); // true
Note that instanceof
won't work for you because you don't have instances, only classes.
Excerpt from Javadoc for Class.isAssignableFrom
:
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false. If this Class object represents a primitive type, this method returns true if the specified Class parameter is exactly this Class object; otherwise it returns false.
How to check if a subclass is an instance of a class at runtime?
You have to read the API carefully for this methods. Sometimes you can get confused very easily.
It is either:
if (B.class.isInstance(view))
API says: Determines if the specified Object (the parameter) is assignment-compatible with the object represented by this Class (The class object you are calling the method at)
or:
if (B.class.isAssignableFrom(view.getClass()))
API says: Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter
or (without reflection and the recommended one):
if (view instanceof B)
java - Class whose name is known at compile time and which extends other class at runtime
Maybe check out ByteBuddy.
You can "make" a new class dynamically, with features that can help support your constraints:
- Using
Class.forName
to load the third party proprietary class without linking to it in your code, you pass the class name as a configuration point - Naming strategy gives you control on the name of generated class
intercept(
Implementation)
to insert your custom code.
Example:
Class<?> dynamicType = new ByteBuddy()
.subclass(Class.forName(thatPeskyProprietaryClass))
.namingStrategy(...)
.method(ElementMatchers.named("someMethod"))
.intercept(...)
.make()
.load(getClass().getClassLoader())
.getLoaded();
Ways to detect whether a C++ virtual function has been redefined in a derived class
You can't check for override of virtual function portably.
You need to bring the knowledge to the Solver
, preferably via type as opposed to run-time flag.
One (type-based) way is to check for presence or absence of a interface, via dynamic_cast
.
A probably better way is to provide overloads of solve function, in your case the Solver
constructor.
Probably better advice could be given if you provided a more concrete description of the problem. It does remind of typical situation where someone (1) needs to solve some problem P, (2) envisions technical approach X as a solution to P, (3) discovers that X doesn't cut it, and (4) asks how to make X work for a vague description of P, or even for some unrelated problem Q. The details of original problem P will often suggest a much better solution than X, and the problems of making X work, irrelevant to solving P.
Related Topics
How to Use the Windows API in Mingw
_Glibcxx_Use_Cxx11_Abi, Gcc 4.8 and Abi Compatibility
Where Does the -Dndebug Normally Come From
Opencv Cv::Mat to Std::Ifstream for Base64 Encoding
Should I Include Stddef.H or Cstddef for Size_T
Can Cython Code Be Compiled to a Dll So C++ Application Can Call It
Specialization of Member Function Template After Instantiation Error, and Order of Member Functions
So_Rcvtime and So_Rcvtimeo Not Affecting Boost.Asio Operations
What's the Difference Between a Compiler's '-O0' Option and '-Og' Option
Why Are C++ Int and Long Types Both 4 Bytes
Opengl: Glgeterror() Returns Invalid Enum After Call to Glewinit()