My question is: is there a way to assess at runtime that notDerived2 actually points to something that do no inherit from Base?
General answer is: no.
C++ doesn't store type information inside pointers to objects, so it can't distinguish between an object and any other piece of memory at runtime.
Hi falconindy, thanks for your reply. Actually I know that static_cast is more appropriate for upcasts, since usually upcasting is safe and does not need any runtime check. Unfortunately, I'm facing a situation where I have a pointer (notDerived2) which is a Derived* and thus is supposed to point to a Derived object, thus nothing is done at runtime to check the validity of upcating to Base; but it actually points to an object which is not a child of Base, so the cast should fail but it doesn't.
I know having a pointer which points to a completely unrelated object might sound quite weird, but that's what happens when trying to dynamically cast to a base type the content of a type erasure (see here for a brief description; by the way, that solution won't work for me since I cannot make my holder inherit from ValueType, for various reasons).
Then your type erasure class needs to give you the support you're looking for. There's no safe way to do this, otherwise.
]]>Derived *notDerived2 = (Derived*)(new NotDerived)
you use C-style type cast. It's not good idea in C++ until you know what you do. It allows to cast a pointer value but behaviour of object is undefined.
]]>You only need dynamic_cast to go from base to derived. If you attempt to call dynamic_cast on a base class and convert it to a class which is not a subclass of base, you get undefined behavior. You can get mostly compile-time checking for the purposes of ensuring that a dynamic_cast from base to derived is safe: see google's implementation of down_cast for an example.
]]>#include <iostream>
class Base{
public:
virtual ~Base(){}
};
class Derived: public Base{};
class NotDerived{
public:
virtual ~NotDerived(){}
};
int main(){
Derived *derived = new Derived;
NotDerived *notDerived = new NotDerived;
Derived *notDerived2 = (Derived*)(new NotDerived);
std::cout << derived << " " << dynamic_cast<Base*>(derived) << std::endl;
std::cout << notDerived << " " << dynamic_cast<Base*>(notDerived) << std::endl;
std::cout << notDerived2 << " " << dynamic_cast<Base*>(notDerived2) << std::endl;
}
Compiling with gcc and executing gives:
0x1bd8c20 0x1bd8c20
0x1bd8c40 0
0x1bd8c60 0x1bd8c60
From the third line one sees that dynamic_cast do not perform any runtime check when upcasting from a pointer to a derived class, even if that pointer actually points to something not belonging to the inheritance line. This is standard behavior, AFAIK. My question is: is there a way to assess at runtime that notDerived2 actually points to something that do no inherit from Base?
Thanks.