У меня есть следующие родительские дочерние простые классы:
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 в качестве аргумента. Какова причина?
ИСПРАВЛЕНО:
Функция, вызывающая 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++.
Вам нужна ссылка здесь, потому что dynamic_cast будет работать, только если реальный тип вашей переменной имеет тип RectBounds:
BoundBases* dummy = new Rectbound();
Здесь вы можете понизить, потому что реальный тип Rectbound, поэтому он будет работать. Если вы передадите его по значению, он создаст копию только части BoundBase вашего объекта, потеряв информацию о вашем реальном типе.
Эта проблема известна как нарезка
Я не уверен, почему вы удивлены этим поведением. BoundBases
переданные по значению, - это просто BoundBases
. Так что dynamic_casting, что для ребенка не может сделать RectBounds
. Это то, что должен делать dynamic_cast.
Если это сработало по-другому: как бы определить, что, например, x, y, если оно дало только BoundBases
. Это не определено.
init
?BoundBases(double, double, double, double)
? В конце концов, вам нужен действительный завершенный объект для выполнения приведения