Reputation: 8354
Why the last command is invalid? The compiler cant resolve.
class IRNode
class IINputBS
class ColumnReaderNode: public IRNode, public IInputBS
ColumReaderNode *col = new ColumnReaderNode();
IRNode *node = col;
IInputBS *bs2 = (IInputBS *)(col); //valid
IInputBS *bs1 = (IInputBS *)(node); //invalid
Upvotes: 0
Views: 69
Reputation: 956
In C++ dynamic_cast
can be used to perform a cross-cast which will allow you to cast across a hierarchy.
class IRNode
class IINputBS
class ColumnReaderNode: public IRNode, public IInputBS
ColumnReaderNode *col = new ColumnReaderNode();
IRNode *node = col;
IInputBS *bs1 = dynamic_cast<IInputBS *>(node); // should work
The dynamic_cast
will succeed in this case (though you may still want to assert that it does) since node
actually does point to an IInputBS
(since it is pointing to a ColumnReaderNode
).
Upvotes: 0
Reputation: 171097
It is a bad idea to use C-style casts in C++ code, and here is why. If you were using C++ casts, the first one could be done with a static_cast
, while the second one would require you to use a reinterpret_cast
to build. And that should trigger a warning sign - a need to use reinterpret_cast
with pointers usually means the compiler doesn't have enough information to do the proper cast.
That's exactly what's happening. Given just a IRNode*
, there is no way to compute a IInputBS*
out of it - they are not related. There could be arbitrarily many classes deriving from these two in arbitrarily complex ways, for example.
You have two options. If you know for certain that your object actually is of a type derived from both (such as ColumReaderNode
in your case) and you just want to get at its other parent, you can use static_cast
to downcast to this, and leave the rest to implicit conversions (or use a static_cast
again, if you feel like it):
IInputBS *bs1 = static_cast<ColumnReaderNode*>(node); // upcast will happen implicitly
IInputBS *bs1 = static_cast<IInputBS*>(static_cast<ColumnReaderNode*>(node)); // explicit, but superfluous upcast
If you do not know for certain that the object is actually of type ColumnReaderNode
, you can use dynamic_cast
. This has a runtime cost, but it will actually do the right thing by inspecting the actual runtime type of the object you're pointing to:
IInputBS *bs1 = dynamic_cast<IInputBS*>(node);
This will do the correct cast if the object is of the appropriate type, or set bs1
to a null value if not.
dynamic_cast
requires the objects involved to be polymorphic (i.e. have at least one virtual
member function), but I would assume this is already fulfilled in your case.
Upvotes: 2
Reputation: 66371
Because IRNode
and IInputBS
are unrelated, so a pointer to one can't be cast to a pointer to the other.
The compiler can't tell what an IRNode*
will point to at runtime.
That col
is an instance of a class related to both these classes is information that you threw away when you cast it to an IRNode
.
Upvotes: 0