-3

I have a base class Shape and derived a few sub classes like Rectangle and Circle. All Shapes should be stored in a 2d vector, according to another 2d vector with characters (every character is representing a shape like 'o' -> Circle).

The method addShapeAtEndOfLine(Shape s, vector* line) should push the object in the vector:

void Game::addShapeAtEndOfLine(Shape s, vector<Shape>* line)
{
  line->push_back(std::move(s));
}

Game::Game(vector<string> game_validate)
{
  for(auto it_a = game_validate.begin() + 2; it_a < game_validate.end(); it_a++)
  {
    vector< Shape > *currentLine = new vector< Shape >();

    string current_line = *it_a;
    for (auto it_b = current_line.begin(); it_b < current_line.end(); it_b++)
    {
      if(*it_b == 'o')
      {
        addShapeAtEndOfLine(new Circle(*it_b), currentLine);
      } else if (*it_b == '#')
      {
        addShapeAtEndOfLine(new Rectangle(*it_b), currentLine);
      }
    }
  }
}

In the header-file i do have a vector like this:

vector < vector < Shape > > field;

Unfortunately this isn't working because it seems, like the constructor of Circle/Rectangle need a reference:

Circle::Circle(char character) : Shape(character) {
}

When trying to compile I receive this error-message:

error: invalid conversion from 'Circle*' to 'char' [-fpermissive]

When I use this instead it works (because it's a reference):

if(*it_b == 'o')
{
  Shape* c = new Circle('o');
  addShapeAtEndOfLine(*c, currentLine);
}

Do you have an idea why this isn't working when I create the object in the method respectively can you tell me what I can do to make it work?

Thanks for help!

Xa Na
  • 31
  • 1
  • 7

1 Answers1

0

Both your addShapeAtEndOfLine() method and your vector<Shape> operate with concrete Shape objects only, not with any descendant objects. You are slicing your objects, which kills polymorphism. Don't slice! Your vector needs to hold Shape* pointers instead.

Also, you have a memory leak in your Game() constructor. You are not freeing currentLine or the Shape objects it holds. Declare currentLine on the stack instead of the heap, and change it to hold std::unique_ptr<Shape> objects instead. This way, you don't have to worry about memory management.

void Game::addShapeAtEndOfLine(Shape *s, vector<std::unique_ptr<Shape>> &line)
{
    line.emplace_back(s);
    // or: line.push_back(std::unique_ptr<Shape>(s));
}

Game::Game(vector<string> &game_validate)
{
    for(auto it_a = game_validate.begin() + 2; it_a != game_validate.end(); ++it_a)
    {
        vector<std::unique_ptr<Shape>> currentLine;

        for (auto it_b: *it_a)
        {
            switch (it_b)
            {
                case 'o':
                    addShapeAtEndOfLine(new Circle(it_b), currentLine);
                    break;

                case '#':
                    addShapeAtEndOfLine(new Rectangle(it_b), currentLine);
                    break;
            }
        }

        // use currentLine as needed...
    }
}
Community
  • 1
  • 1
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770