类型Cast - C ++

时间:2014-05-12 13:48:26

标签: c++ inheritance type-conversion

为什么最后一个命令无效?编译器无法解决。

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

3 个答案:

答案 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)

因为IRNodeIInputBS不相关,所以指向一个的指针不能转换为指向另一个的指针。

编译器无法分辨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}})。