динамическое приведение не удается при переходе от родительского к дочернему

0

У меня есть следующие родительские дочерние простые классы:

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++.

  • 0
    не могли бы вы показать, как вы называете init ?
  • 0
    Может ли это быть из-за отсутствия объявления конструктора по умолчанию BoundBases(double, double, double, double) ? В конце концов, вам нужен действительный завершенный объект для выполнения приведения
Показать ещё 2 комментария
Теги:
casting
downcasting
dynamic-cast

2 ответа

3
Лучший ответ

Вам нужна ссылка здесь, потому что dynamic_cast будет работать, только если реальный тип вашей переменной имеет тип RectBounds:

BoundBases* dummy = new Rectbound();

Здесь вы можете понизить, потому что реальный тип Rectbound, поэтому он будет работать. Если вы передадите его по значению, он создаст копию только части BoundBase вашего объекта, потеряв информацию о вашем реальном типе.

Эта проблема известна как нарезка

0

Я не уверен, почему вы удивлены этим поведением. BoundBases переданные по значению, - это просто BoundBases. Так что dynamic_casting, что для ребенка не может сделать RectBounds. Это то, что должен делать dynamic_cast.

Если это сработало по-другому: как бы определить, что, например, x, y, если оно дало только BoundBases. Это не определено.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню