如何在列表中调用对象的函数?

时间:2014-05-03 20:23:32

标签: c++ list inheritance polymorphism

我正在制作一个油漆程序。程序将按照绘制的顺序存储在图形窗口上绘制的元素。我想使用" LIST"存储绘制的形状。形状具有不同的类型,即allShapes是父类,line是子类。请告诉我如何在allShapes列表中存储一行并调用它的功能。

以下是示例代码:

    class allShapes
    {
     protected:
     int * points; //vertices of the shape
     int color; //color of the shape
     int n; //no. of points
        public:
    //virtual void draw()= 0;
    virtual void draw()
    {

    }
};
       class line:public allShapes
       {
         public:
     line()
     {
    points = new int[4];
    n = 2;
     }
    void draw()
   {
        //Code here
       }
      };


    int main()
   {

int mouse_x, mouse_y;
char key_pressed;
GP142_open();           /* Open and initialize the GP142 Graphics Window    */
list<allShapes> shapes;
int quit = 0;
while (!quit) {

    switch (GP142_await_event(&mouse_x, &mouse_y, &key_pressed)) {

    case GP142_MOUSE:
        if ((mouse_x > -490 && mouse_x<-445) && (mouse_y>305 && mouse_y < 360)) // If user selects the draw line option
        {
            line newLine;
            shapes.push_back(newLine);
            allShapes check = shapes.front();
            check.draw();
        }
        break;
    case GP142_QUIT:
        quit = 1;
        break;
    default:
        break;
    }
}
   }

但程序不会调用line对象的draw函数。我在allShapes中也有虚拟函数绘制。如何调用check.draw()在屏幕上画一条线?

2 个答案:

答案 0 :(得分:1)

对于多态对象,您无法为基类保留足够的存储空间,然后期望能够将任何派生类阻塞到该空间中。当你说:

时,你就是这么做的
list<allShapes> shapes;

每当您尝试将line卡入allShapes对象的空间时,将会发生allShapes line部分的存储, line部分将被忽略。那么你有一个不是line的对象,并且在其上调用.draw()将不会调用line::draw()。在给定对象的动态类型draw()的情况下,它将调用正确的allShapes方法。

当你说:

时,同样的事情再次发生
allShapes check = shapes.front();
check.draw();

shapes.front()的任何类型结果都会转换为allShapes。如果您有一个line的列表,那么它将在此处转换为allShapes

使用多态通常需要使用指针或引用:

list<unique_ptr<allShapes>> shapes;

现在您可以将行放入此集合中:

shapes.push_back(make_unique<line>()); // make_unique is C++14

这样line不会转换为allShapes,所以当完成虚拟调度以根据对象的真实动态类型找到正确的方法时,draw()方法将使用line

要访问列表中的对象,您可以使用引用:

allShapes &check = shapes.front();
check->draw();

如果您使用默认使用引用类型的语言(例如Java或C#)来使用C ++,那么您真的需要了解C ++值类型的工作原理。在其他语言中,您可以在所有地方使用指针,但语法并没有那么明显。要在C ++中使用指针,必须显式使用特殊的指针语法。

您可能会找到另一个答案,其中我介绍了这个有用的内容:Confused with object arrays in C++

答案 1 :(得分:0)

问题在于:

        line newLine;
        shapes.push_back(newLine);
        allShapes check = shapes.front();
        check.draw();

复制线对象,而非引用。 容器shapes不应由对象组成,而应由指针组成。 如果将线对象复制到allShapes对象中,allShapes对象将不会变为line

将容器声明为

list<allShapes*> shapes;

然后写

        line* newLine = new line();
        shapes.push_back(newLine);
        allShapes* check = shapes.front();
        check->draw();

并记住某处的delete对象。