为什么最后一个命令无效?编译器无法解决。
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
答案 0 :(得分:2)
在C ++代码中使用C风格的强制转换是个坏主意,这就是原因所在。如果您使用的是C ++强制转换,第一个可以使用static_cast
完成,而第二个则需要使用reinterpret_cast
来构建。这应该触发一个警告标志 - 需要使用带有指针的reinterpret_cast
通常意味着编译器没有足够的信息来进行正确的演员。
这正是发生了什么。仅给出一个IRNode*
,就无法计算出IInputBS*
- 它们不相关。例如,可以以任意复杂的方式从这两个类中衍生出任意多个类。
您有两种选择。如果您确定您的对象实际上是从两者派生的类型(例如您的ColumReaderNode
)并且您只想获取其他父级,则可以使用static_cast
向下转换为这个,剩下的就是隐式转换(如果你愿意,可以再次使用static_cast
):
IInputBS *bs1 = static_cast<ColumnReaderNode*>(node); // upcast will happen implicitly
IInputBS *bs1 = static_cast<IInputBS*>(static_cast<ColumnReaderNode*>(node)); // explicit, but superfluous upcast
如果您不确定对象实际上是ColumnReaderNode
类型,则可以使用dynamic_cast
。这有运行时成本,但它实际上会通过检查您指向的对象的实际运行时类型来做正确的事情:
IInputBS *bs1 = dynamic_cast<IInputBS*>(node);
如果对象属于适当的类型,这将执行正确的强制转换,或者如果不是,则将bs1
设置为空值。
dynamic_cast
要求所涉及的对象具有多态性(即至少有一个virtual
成员函数),但我认为这已经在你的情况下已经实现了。
答案 1 :(得分:0)
因为IRNode
和IInputBS
不相关,所以指向一个的指针不能转换为指向另一个的指针。
编译器无法分辨IRNode*
在运行时将指向的内容。
col
是与这两个类相关的类的实例,是您在将其转换为IRNode
时丢弃的信息。
答案 2 :(得分:0)
在C ++中,dynamic_cast
可用于执行交叉投射,允许您在层次结构中进行投射。
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
dynamic_cast
在这种情况下会成功(尽管你可能仍然想断言它确实如此),因为node
实际上确实指向IInputBS
(因为它指向一个{ {1}})。