动态转换在从父级到子级的向下转换时失败

时间:2014-02-25 16:58:15

标签: c++ casting dynamic-cast downcast

我有以下父子简单类:

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 ++的新手。

2 个答案:

答案 0 :(得分:3)

这里需要一个引用,因为只有当变量的实际类型是RectBounds类型时,dynamic_cast才会起作用:

BoundBases* dummy = new Rectbound();

你可以向下转发,因为真正的类型是Rectbound,所以它会起作用。 如果按值传递它,它将只创建对象的BoundBase部分的副本,丢失有关您的实际类型的信息。

此问题称为slicing

答案 1 :(得分:0)

我不确定为什么你会对这种行为感到惊讶。按值传递的BoundBases只是BoundBases。因此,给孩子的dynamic_casting不能成为RectBounds。这正是dynamic_cast应该做的。

如果它的工作方式不同:如何确定例如x,y是否仅给出BoundBases。这没有定义。