Question

I'm working on a paint program. The program will store the elements drawn on the graphics window in the sequence they are drawn. I want to use "LIST" to store the shapes drawn. Shapes are of different types i.e. allShapes is the parent class and line is a child class. Please tell me how to store a line inside allShapes list and call its function.

Here's the sample code:

    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;
    }
}
   }

But the program does not call the draw function of line object. I have virtual function draw in allShapes too. How can I call check.draw() to draw a line on the screen?

Was it helpful?

Solution 2

The problem is here:

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

you are copying the line object, instead of referencing it. The container shapes should not consist of objects, but of pointers to objects. If you copy a line object into a allShapes object, the allShapes object will not turn into a line.

Declare the container as

list<allShapes*> shapes;

and then write

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

and remember to delete the objects somewhere.

OTHER TIPS

With polymorphic objects you cannot reserve just enough storage for the base class and then expect to be able to jam any derived class into that space. That's what you're doing when you say:

list<allShapes> shapes;

Any time you try to jam a line into the space for an allShapes object, what will happen is that the allShapes part of the line will get stored, and the line part will be ignored. So then you've got an object that is not a line, and calling .draw() on it will not call the line::draw(). It will call the correct draw() method given the dynamic type of the object, which is allShapes.

And the same thing happens again when you say:

allShapes check = shapes.front();
check.draw();

Whatever type results from shapes.front() is converted into allShapes. If you had a list of lines then it would be converted to allShapes here.

Using polymorphism generally requires using pointers or references:

list<unique_ptr<allShapes>> shapes;

Now you can put lines into this collection:

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

This way the line does not get converted into an allShapes, and so when virtual dispatch is done to find the correct method based on the object's real dynamic type, the draw() method for line will be used.

In order to access an object in the list you can use a reference:

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

If you're coming to C++ from a language that uses reference types by default, such as Java or C#, then you really need to understand how C++ value types work. In those other languages you use pointers all over the place but the syntax doesn't make that obvious. To use pointers in C++ you have to explicitly use special pointer syntax.

You might find another answer where I cover this useful: Confused with object arrays in C++

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top