Question

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
Was it helpful?

Solution

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.

OTHER TIPS

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top