C ++重写方法(C++ Overriding Methods)

2019-07-31 09:45发布

我也弄不清是什么了这一点。

我有一个具有实体的载体,并允许您从场景中添加并获得实体场景类:

class Scene {
    private:
        // -- PRIVATE DATA ------
        vector<Entity> entityList;
    public:
        // -- STRUCTORS ---------
        Scene();
        // -- PUBLIC METHODS ----
        void addEntity(Entity); // Add entity to list
        Entity getEntity(int); // Get entity from list
        int entityCount();
};

我的实体类如下(输出是用于测试):

class Entity {
    public:
        virtual void draw() { cout << "No" << endl; };
};

然后,我有一个从实体继承的Polygon类:

class Polygon: public Entity
{
    private:
        // -- PRIVATE DATA ------
        vector<Point2D> vertexList; // List of vertices
    public:
        // -- STRUCTORS ---------
        Polygon() {}; // Default constructor
        Polygon(vector<Point2D>); // Declare polygon by points
        // -- PUBLIC METHODS ----
        int vertexCount(); // Return number of vertices
        void addVertex(Point2D); // Add vertex
        void draw() { cout << "Yes" << endl; }; // Draw polygon
        // -- ACCESSORS ---------
        Point2D getVertex(int); // Return vertex
};

正如你所看到的,它应该重写它从实体类继承的draw()方法平局()方法。

但事实并非如此。 当使用如下代码:

scene->getEntity(0).draw();

其中,实体0是一个多边形(或至少应该是),它打印“否”从父方法(就像它不是一个多边形,只是一个实体)。 事实上,它似乎并没有让我叫独特的多边形的方法没有得到:

一些方法名 ”:是不是“实体”的成员

所以任何想法是怎么回事?

谢谢您的帮助。

更新:

所以,我实现了在第一个答案给定的代码,但我不知道如何将我的多边形添加到列表中。 像这样的事情?

const tr1::shared_ptr<Entity>& poly = new Polygon;
poly->addVertex(Point2D(100,100));
poly->addVertex(Point2D(100,200));
poly->addVertex(Point2D(200,200));
poly->addVertex(Point2D(200,100));
scene->addEntity(poly);

我只是不习惯这种shared_ptr的业务。

Answer 1:

我认为你需要发布你的调用代码,但基本上问题是这样的。

你有一个具体的类Polygon从其他具体类派生Entity 。 你addEntity和getEntity功能采取并返回一个Entity ,所以如果您尝试通过或检索的价值 Entity ,你只能复制Entity那个对象(切片吧)和关于对象的衍生部分的信息的一部分,将是丢失。

此外,您有一个vectorEntity ,这是基类对象的矢量,所以你没有存储比基础类型的对象之外的任何方式。

如果你需要有一个混合型的对象的集合,但都来源于Entity ,你可能需要使用动态创建的对象和某种智能指针如tr1::shared_ptrboost::shared_ptr

class Scene {
    private:
        // -- PRIVATE DATA ------
        vector< std::tr1::shared_ptr<Entity> > entityList;
    public:
        // -- STRUCTORS ---------
        Scene();
        // -- PUBLIC METHODS ----
        void addEntity( const std::tr1::shared_ptr<Entity>& ); // Add entity to list
        const std::tr1::shared_ptr<Entity> getEntity(int); // Get entity from list
        int entityCount();
};

编辑

更新后的调用代码基本上是正确的,但使用本地const引用到一个共享的指针是有点模糊。

我可能会喜欢的东西去:

std::tr1::shared_ptr<Polygon> poly( new Polygon );
poly->addVertex(Point2D(100,100));
poly->addVertex(Point2D(100,200));
poly->addVertex(Point2D(200,200));
poly->addVertex(Point2D(200,100));
scene->addEntity(poly);


Answer 2:

chollida的评论是正确的:你推式多边形的对象变成意味着实体类型的存储位置,并运行到什么叫做切片 。 额外的“多边形”信息被剪切掉,你就只剩下实体。

您应该存储指针(或引用,如果可能的话),在这种情况下,以基类。



Answer 3:

您应该使用纯虚函数这一点。

class Entity
{
public:
    virtual void draw() = 0;
};

然后从你的对象调用绘制函数,你也应该使用指针你的对象。



Answer 4:

您应该存储在首位指针(智能指针最好:)),以实体实例。 当插入所以你的对象甚至调用getter方法之前,切片矢量被重新分配。

对getter方法的返回类型也应该是一个指针或引用,所以你就可以作出这样的polimorphic电话。



Answer 5:

作为一个经验法则,你应该总是使用(通过指针或引用即访问对象)引用语义,而不是与你打算使用多态对象打交道时,值语义。

为了确保这种方式的安全性,它是明智的基类所有的多态类型的不可复制通过创建一个私有的拷贝构造函数和赋值操作符。 这将有效地防止切片作为代码只会失败,如果值语义错误地用来请编译。



文章来源: C++ Overriding Methods