我有以下父子简单类:
class BoundBases{
public:
virtual ~BoundBases() { }
};
// Rectangular Bounds for tree
class RectBounds : public BoundBases{
public:
// x, y center point
double x, y;
double w, h;
~RectBounds(){ }
// (_x, _y): center of rectangle bound. (_w, _h): width and height
RectBounds(double _x, double _y, double _w, double _h){
x = _x;
y = _y;
w = _w;
h = _h;
}
//... more functions
};
我还有以下功能结构:
void MyClass::init( BoundBases &bounds, std::vector<int> &colsPartitioned)
{
printf("init - new\n");
BoundBases * bPtr = &bounds;
RectBounds * rBounds = dynamic_cast<RectBounds *>(bPtr);
if(rBounds){
// do something
}else{
throw runtime_error("dynamic cast fail");
}
}
即使我将RectBounds类型的函数作为参数调用,动态转换也会失败。是什么原因?
FIXED:
调用init的函数按值传递BoundBases,如下所示:
MyClass2::MyClass2( BoundBases boundBases, std::vector<int> colsPartitioned) { // creates new table
// set up partition
partScheme_ -> setColsPartitioned(colsPartitioned);
partScheme_ -> setBoundBases(boundBases);
partScheme_ -> init(boundBases, colsPartitioned);
}
我将签名更改为通过引用传递并且它有效。 (安培; boundBases)。有人可以解释为什么会这样吗?我是C / C ++的新手。
答案 0 :(得分:3)
这里需要一个引用,因为只有当变量的实际类型是RectBounds类型时,dynamic_cast才会起作用:
BoundBases* dummy = new Rectbound();
你可以向下转发,因为真正的类型是Rectbound,所以它会起作用。 如果按值传递它,它将只创建对象的BoundBase部分的副本,丢失有关您的实际类型的信息。
此问题称为slicing
答案 1 :(得分:0)
我不确定为什么你会对这种行为感到惊讶。按值传递的BoundBases
只是BoundBases
。因此,给孩子的dynamic_casting不能成为RectBounds
。这正是dynamic_cast应该做的。
如果它的工作方式不同:如何确定例如x,y是否仅给出BoundBases
。这没有定义。