C ++重写方法没有得到所谓的(C++ Overridden method not getting

2019-08-07 15:45发布

Shape.h

namespace Graphics {
    class Shape {
    public:
        virtual void Render(Point point) {};
    };
}

Rect.h

namespace Graphics {
    class Rect : public Shape {
    public:
        Rect(float x, float y);
        Rect();
        void setSize(float x, float y);
        virtual void Render(Point point);

    private:
        float sizeX;
        float sizeY;
    };
}

struct ShapePointPair {
    Shape shape;
    Point location;
};

使用这样的:

std::vector<Graphics::ShapePointPair> theShapes = theSurface.getList();

for(int i = 0; i < theShapes.size(); i++) {
    theShapes[i].shape.Render(theShapes[i].location);
}

此代码最终调用Shape::Render ,而不是Rect::Render

我猜想这是因为它是铸造RectShape ,但我没有任何想法如何阻止它这样做。 我试图让每个形状控制它是如何通过重写渲染Render方法。

任何想法如何实现这一目标?

Answer 1:

这是你的问题:

struct ShapePointPair {
        Shape shape;
        Point location;
};

您存储Shape 。 你应该存储Shape * ,或shared_ptr<Shape>或东西。 但不是一个Shape ; C ++是不是Java。

当您指定一个RectShape ,只有Shape的部分被复制(这是对象切片 )。



Answer 2:

这个问题被称为切片 - 复制到基地当你失去的衍生功能。 为了避免这种使用指针的基类,即

std::vector<Graphics::Shape*> s;
s.push_back(&some_rect);


Answer 3:

问题是,在您的载体要存储形状对象的副本,并复制一个形状对象不复制其派生类的数据或功能-你切的多态了。

使用新的管理对象和删除,并安排您的矢量的指针存储到他们。



Answer 4:

所述多态性将只从一个指针到工作的形状,而不是从一个形状对象。



Answer 5:

你是直接访问图形对象的覆盖工作,你需要通过指针或引用访问对象。

例如,当你assigne造型融入ShapePointPair代码将“片”的对象,只有形状位复制到ShapePointPair

这样做将意味着你必须注意内存管理 - 所以你可以使用在结构ShapePointPair {smart_pointer形状的智能指针; Point location; 点位置; }; };



Answer 6:

不,它不是铸造。

您可以代替存储参照基类点:

struct ShapePointPair {
        Shape shape;
        Point &location;
};

此引用必须在施工时间结构ShapePointPair进行设置。 添加一个构造函数来ShapePointPair用于这一目的。 它必须通过(新建)矩形的实例。

此外观察内存管理responsiblities(适当的书面析构函数等)。



Answer 7:

你可以尝试的boost :: ptr_vector

http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html



Answer 8:

我不知道的好,因为我的英语很差解释。

我想你应该有使用它引用或指针类型。 因为形状精确定义它有什么做的。

如果你直接使用你的代码,你的孩子尝试复制和形状做的工作。 这就是为什么不工作,你的覆盖功能。

使用指针或引用这样。

pointer.h

class Parent {
public:
    virtual void work() { printf("parent is working now\n"); }
};
class Child1 {
public:
    virtual void work() { printf("child1 is working now\n"); }
};
class Child2 {
public:
    virtual void work() { printf("child2 is working now\n"); }
};
struct Holder {
    Parent* obj1;
    Parent* obj2;
};
int main() {
    Child1 child1;
    Child2 child2;
    Holder holder = { &child1, &child2 };
    holder.obj1->work();
    holder.obj2->work();
    return 0;
}

reference.h

class Parent {
public:
    virtual void work() { printf("parent is working now\n"); }
};
class Child1 {
public:
    virtual void work() { printf("child1 is working now\n"); }
};
class Child2 {
public:
    virtual void work() { printf("child2 is working now\n"); }
};
struct Holder {
    Parent& obj1;
    Parent& obj2;
};
int main() {
    Child1 child1;
    Child2 child2;
    Holder holder = { child1, child2 };
    holder.obj1.work();
    holder.obj2.work();
    return 0;
}

* PS:我个人使用抽象函数(虚拟无效的东西()= 0;)。 因为我也忘了,有时,所以我抓住它的语法错误。



文章来源: C++ Overridden method not getting called