C++ C++;未调用重写的方法

C++ C++;未调用重写的方法,c++,inheritance,virtual,overriding,C++,Inheritance,Virtual,Overriding,形状.h 矩形h namespace Graphics { class Shape { public: virtual void Render(Point point) {}; }; } 这样使用: namespace Graphics { class Rect : public Shape { public: Rect(float x, float y); Rect(); void set

形状.h

矩形h

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

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 theShapes=theSurface.getList();
for(int i=0;i
这段代码最后调用的是
Shape::Render
,而不是
Rect::Render

我假设这是因为它正在将
Rect
转换为
形状
,但我不知道如何阻止它这样做。我试图通过覆盖
Render
方法让每个形状控制它的渲染方式


关于如何实现这一点,您有什么想法吗?

多态性只能从指向形状的指针开始工作,而不能从形状对象开始工作。

这是您的问题:

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

for(int i = 0; i < theShapes.size(); i++) {
    theShapes[i].shape.Render(theShapes[i].location);
}
您正在存储一个
形状
。您应该存储一个
形状*
,或者一个
共享的\u ptr
或其他东西。但不是一个
形状
;C++不是java .< /p>
Rect
指定给
形状时,仅复制
形状
部分(这是对象切片)。

此问题称为切片-复制到基础时,会丢失衍生功能。 要避免这种情况,请使用指向基类的指针,即

struct ShapePointPair {
        Shape shape;
        Point location;
};
std::向量s;
s、 向后推(&some-rect);

问题在于,在向量中,您存储的是形状对象的副本,而复制形状对象并不会复制其派生类的数据或功能—您是唯一的选择


使用“新建”和“删除”管理对象,并安排向量存储指向它们的指针。

您正在直接访问形状对象,以便覆盖工作。您需要通过指针或引用访问对象

例如,当您将形状分配到ShapePointPair中时,代码将“切片”对象,并且仅将形状位复制到ShapePointPair中

这样做意味着您必须观察内存管理,以便在结构中使用智能指针 形状点对{ 智能指针形状; 点定位; };

不,它不是铸造

您可以存储对基类点的引用:

std::vector<Graphics::Shape*> s;
s.push_back(&some_rect);
必须在构造结构时设置此引用 形状点对。将构造函数添加到此的ShapePointPair 目的。必须传递(新创建的)的实例 矩形

还要遵守内存管理职责(正确
你可以试试boost::ptr_vector


由于我的英语不好,我不确定能否解释清楚

我认为您应该使用它的引用或指针类型。 因为形状是精确定义的,它必须做什么

如果您直接使用您的代码,您的孩子会尝试复制并执行shape的工作。 这就是为什么你的覆盖功能不起作用

使用指针或引用 像这样

指针.h

struct ShapePointPair {
        Shape shape;
        Point &location;
};
参考文献.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:我个人使用抽象函数(virtualvoidsomething()=0;)。
因为我有时也会忘记它,所以我认为它是语法错误。

也许你想向我们展示创建向量元素的代码?问题和解决方案与这个问题几乎相同。在这里,您有一个具体基类的向量(struct containing a),如果您希望调用Rect::Render,则必须通过切片派生类来创建该向量。当ShapePointPair在向量库中复制时,auto_ptr将丢失数据。我一直希望在没有指针的情况下完成这项工作,因为形状不会占用太多内存,所以很容易在堆栈上复制,但这似乎是不可能的。谢谢大家的快速回复。谢谢。我以前没听说过切片,下次会记住这一点。
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;
}