0

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

Saher Ahwal
  • 9,015
  • 32
  • 84
  • 152

2 Answers2

3

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

Community
  • 1
  • 1
Kiroxas
  • 891
  • 10
  • 24
0

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.

dornhege
  • 1,500
  • 8
  • 8