C ++ - 在方法

时间:2016-04-14 20:12:07

标签: c++

我有一个基类 Shape ,并派生了一些子类,如 Rectangle Circle 。根据另一个带字符的2d向量,所有形状应存储在2d向量中(每个字符代表一个像'o' - > Circle的形状)。

方法 addShapeAtEndOfLine(Shape s,vector * line)应该在向量中推送对象:

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

在标题文件中,我有一个这样的矢量:

vector < vector < Shape > > field;

不幸的是,这不起作用,因为看起来像Circle / Rectangle的构造函数需要引用:

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

尝试编译时收到此错误消息:

  

错误:从'Circle *'无效转换为'char'[-fpermissive]

当我使用它时,它可以工作(因为它是一个参考):

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

当你分别在方法中创建对象时,你是否知道为什么这不起作用你能告诉我我能做些什么来使它工作吗?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

addShapeAtEndOfLine()方法和vector<Shape>只能使用具体的Shape个对象,而不能使用任何后代对象。你是slicing你的对象,它会杀死多态。不切片!您的vector需要保留Shape*个指针。

此外,您的Game()构造函数中存在内存泄漏。您没有释放currentLine或其拥有的Shape个对象。在堆栈而不是堆上声明currentLine,并将其更改为保留std::unique_ptr<Shape>个对象。这样,您就不必担心内存管理。

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