2017-05-03 6 views
0

Ich habe das folgende Problem: Ich wollte ein Projekt von guten alten C bis C++ wiederholen und alles class(y) :) machen und es von Anfang an skalierbar.C++ verwenden Sie eine Klasse in einer Klasse (in einer Klasse) und rufen Sie ihre Funktionen

Es ist eine Simulation von Zellen (als Teil eines Schwarms) auf einem Gitter, so habe ich beschlossen, die folgende Struktur:

class Simulation has an instance of 
class Grid  has an instance of 
class Swarm  has an instance of 
class Cell 

ich die Klassen in separaten Header-Dateien definiert. Dann muss ich natürlich Funktionen in Grid, Schwarm und Zelle aufrufen können. Ich wollte es gerade nach vorn tun:

Simulation mysim; 
mysim.get_grid(0).any_function_here(); 

mit dem Netz als Rückgabeparameter

Grid Sim::get_grid(int grid_no) 
{ 
    std::cout << "sim.get_grid(" << grid_no << ") called." << std::endl; 
    if (grid_no <= amount_of_grids) 
     return this->test;//##//this->gridlist[grid_no]; 
    else 
     std::cout << "you have not created this grid number yet" << std::endl; 

    Grid dummy; 
    return dummy; 
} 

Es ruft die Funktion und funktioniert, solange keine Änderungen im Netz vorgenommen werden. Diese scheinen im Weltraum verloren zu sein. Wahrscheinlich ein Zeiger Fehler, aber ich kann nicht einen Fehler finden, da genau der gleiche Code für die Simulation Klasse arbeitet ...

Weitere Quelle:

int Grid::create_swarm(std::string name) 
{ 
    Swarm new_swarm; 
    new_swarm.set_name("Protoswarm"); 
    swarmlist.push_back(new_swarm); 
    this->amount_of_swarms ++; 
    std::cout << "amount_of_swarms = " << amount_of_swarms << std::endl; 
    return 0; 
} 

Swarm Grid::get_swarm(int swarm_no) 
{ 
    std::cout << "grid.get_swarm(" << swarm_no << ") called." << std::endl; 
    if (swarm_no <= amount_of_swarms) 
     return swarmlist[swarm_no]; 
    else 
     std::cout << "oh oh - you have not this swarm in here..." << std::endl; 

    Swarm dummy; 
    return dummy; 
} 

ich die create_swarm Funktion aufrufen kann so oft wie ich wollen, aber die Schwärme erscheinen nie und der Zähler steigt nicht in diesem Raster, nur vorübergehend, solange die Funktion da drin ist. Fehle ich etwas? Ist es wirklich nur ein Zeigerfehler? Warum funktioniert dieser Code, wenn ich es so nennen:

Grid newgrid; 
newgrid.create_swarm(); 

A schnell c & p'ed MWE

#include <iostream> 
#include <string> 
#include <vector> 

class Sim 
{ 
    public: 
     Sim(); 
     virtual ~Sim(); 

     Grid get_grid(int grid_no); 

    protected: 

    private: 
     std::vector<Grid> gridlist; 
     int amount_of_grids = -1; 
}; 


class Grid 
{ 
    public: 
     Grid(); 
     virtual ~Grid(); 

     int set_size(int x, int y); 
     int create_swarm(std::string name); 
     Swarm get_swarm(int swarm_no); 
     void print_swarms(); 

    protected: 

    private: 
     std::vector<Swarm> swarmlist; 
     int amount_of_swarms = -1; 
     /*static const*/ int size_x; 
     /*static const*/ int size_y; 
     std::vector<std::vector<Field>> fields; 
     std::string gridname; 
}; 

Grid Sim::get_grid(int grid_no) 
{ 
    std::cout << "sim.get_grid(" << grid_no << ") called." << std::endl; 
    if (grid_no <= amount_of_grids) 
     return this->gridlist[grid_no]; 
    else 
     std::cout << "you have not created this grid number yet" << std::endl; 

    Grid dummy; 
    return dummy; 
} 

int Grid::create_swarm(std::string name) 
{ 
    Swarm new_swarm; 
    new_swarm.set_name("Protoswarm"); 
    swarmlist.push_back(new_swarm); 
    this->amount_of_swarms ++; 
    std::cout << "amount_of_swarms = " << amount_of_swarms << std::endl; 
    return 0; 
} 

Swarm Grid::get_swarm(int swarm_no) 
{ 
    std::cout << "grid.get_swarm(" << swarm_no << ") called." << std::endl; 
    if (swarm_no <= amount_of_swarms) 
     return swarmlist[swarm_no]; 
    else 
     std::cout << "oh oh - you have not this swarm in here..." << std::endl; 

    Swarm dummy; 
    return dummy; 
} 


using namespace std; 
int main(int argc, char* argv[]) 
{ 
    Sim mysim; 
    mysim.create_grid(); 
    mysim.get_grid(0).create_swarm("Alpha-Swarm"); 
    mysim.get_grid(0).create_swarm("Betaa-Swarm"); //doesn't work 

    Grid newgrid; 
    newgrid.create_swarm("Gamma-Swarm"); 
    newgrid.create_swarm("Delta-Swarm"); // works, but is not needed. 

    return 0; 
} 
+0

Fügen Sie nach Möglichkeit ein [MCVE] ein. – tambre

+2

Das Zurückgeben einer Klasse in C++ entspricht genau dem Zurückgeben einer Struktur in "good old" C; es erstellt eine Kopie. – molbdnilo

+0

Ohne [mcve] ist es schwer zu sagen, aber es sieht so aus, als ob das Problem darin besteht, dass Sie keine Referenzen auf die Daten im Vektor zurückgeben. – NathanOliver

Antwort

0
Grid Sim::get_grid(int grid_no) {...} 

Sie werden nach Wert, nicht per Referenz zurückgegeben. Das bedeutet, dass das, was Sie zurückgeben, eine Kopie Ihres tatsächlichen Mitglieds ist. In Ihrem Fall möchten Sie jedoch als Referenz zurückkehren, um Änderungen am ursprünglichen Objekt vornehmen zu können. Der Code würde

Grid& Sim::get_grid(int grid_no) {...} 

Beachten Sie jedoch, dass Sie nicht in der Lage sein wird, alle Provisorien auf diese Weise (wie Ihr dummy Grid) zurück, so dass Sie Ihre Methoden ändern müssen, um dieses Problem zu umgehen. Wenn Sie dies nicht tun möchten, könnten Sie immer noch einen Zeiger zurückgeben, obwohl dies die Syntax ein wenig ändern würde.

0

Ihre get_grid und get_swarm Methoden Kopien von Original-Array-Elemente zurück. Sie sollten stattdessen einen Verweis (oder einen Zeiger) auf Grid oder Swarm zurückgeben.

Verwandte Themen