dynamic cast fails on downcasting from parent to child
-
21-12-2019 - |
Question
I have the following parent child simple classes:
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
};
I also have the following function structure:
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");
}
}
The dynamic cast is failing even though I call the function with RectBounds type as an argument. What is the reason?
FIXED:
The function calling init passed BoundBases by value, as follows:
MyClass2::MyClass2( BoundBases boundBases, std::vector<int> colsPartitioned) { // creates new table
// set up partition
partScheme_ -> setColsPartitioned(colsPartitioned);
partScheme_ -> setBoundBases(boundBases);
partScheme_ -> init(boundBases, colsPartitioned);
}
I changed the signature to pass by reference and it worked. (&boundBases). Can someone explain why is that? I am new to C/C++.
La solution
You need a reference here because dynamic_cast will only work if the real type of your variable is of type RectBounds like :
BoundBases* dummy = new Rectbound();
You can downcast here because the real type is Rectbound, so it will work. If you pass it by value, it will create a copy of only the BoundBase part of your object, losing the information about your real type.
This problem is known as slicing
Autres conseils
I'm not sure why you are surprised by that behavior. BoundBases
passed by value is just a BoundBases
. So dynamic_casting that to a child cannot make that a RectBounds
. That's exactly what dynamic_cast is supposed to do.
If it worked differently: How would it be determining what e.g. x,y are if it's only given a BoundBases
. This is not defined.