2016-04-14 12 views
-3

Ich habe eine Basisklasse Form und abgeleitete einige Unterklassen wie Rechteck und Kreis . Alle Shapes sollten in einem 2d-Vektor gespeichert werden, entsprechend einem anderen 2D-Vektor mit Zeichen (jedes Zeichen repräsentiert eine Form wie 'o' -> Circle).C++ - Objekt erstellt in Methode übergeben

Verfahren addShapeAtEndOfLine (Shape s, Vektor * line) sollte das Objekt im Vektor drücken:

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

Im Header-Datei tun einen Vektor wie folgt ich habe:

vector < vector <Shape> > field; 

Leider funktioniert das nicht, weil es scheint, als ob der Konstruktor von Circle/Rectangle eine Referenz benötigt:

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

Wenn ich versucht, diese Fehlermeldung zu kompilieren:

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

Wenn ich diese verwenden, anstatt es funktioniert (weil es eine Referenz ist):

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

Haben Sie eine Idee haben, warum diese isn Ich arbeite nicht, wenn ich das Objekt in der Methode erstelle. Kannst du mir sagen, was ich tun kann, damit es funktioniert?

Vielen Dank für Ihre Hilfe!

+2

Sie tun alles falsch. Suchen Sie nach Objekt-Slicing. – NathanOliver

+0

Was ist 'b'? Was ist "Mauer"? – aschepler

+0

Danke für die Erwähnung -/edit. –

Antwort

0

Sowohl Ihre addShapeAtEndOfLine() Methode als auch Ihre vector<Shape> arbeiten nur mit konkreten Shape Objekten, nicht mit irgendwelchen Nachkommenobjekten. Sie sind slicing Ihre Objekte, die Polymorphie tötet. Nicht schneiden! Ihr vector muss stattdessen Shape* Zeigern halten.

Sie haben auch einen Speicherverlust in Ihrem Game() Konstruktor. Sie befreien nicht currentLine oder die Shape Objekte, die es hält. Deklarieren Sie currentLine auf dem Stapel anstelle des Heap, und ändern Sie es, um stattdessen std::unique_ptr<Shape> Objekte zu halten. Auf diese Weise müssen Sie sich nicht um die Speicherverwaltung kümmern.

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