2017-07-03 2 views
2

J'utilise un baseclass abstrait avec seulement des méthodes virtuelles pures, pour avoir un comportement d'interface (oui, je viens de Java) en C++. Pour autant que j'ai fait mes recherches, cela semble être la voie à suivre.C++ "Méthode virtuelle pure appelée" avec utilisation de la classe de base abstraite

Je dois résumer les classes de base, GraphReader et Graph.

class Graph{ 
    public: 
    Graph() {}; 
    virtual ~Graph() {}; 
    virtual void layout() = 0; 
    virtual std::vector<std::shared_ptr<Node>> getNodes() = 0; 
    virtual std::vector<std::shared_ptr<Edge>> getEdges() = 0; 

    protected: 

}; 

class GraphReader{ 
    public: 
    GraphReader(std::string fileName_) : 
     fileName(fileName_) {}; 
    virtual ~GraphReader() {}; 
    virtual Graph* read() = 0; 

    protected: 
    std::string fileName; 
}; 

Ces deux classes ont des classes dérivées qui héritent de GraphReader/Graph.

class OgdfGraph : public Graph{ 
    public: 
    OgdfGraph(); 
    virtual ~OgdfGraph(); 
    void setOgdfGraph(ogdf::Graph &oGraph); 
    std::vector<std::shared_ptr<Node>> getNodes(); 
    std::vector<std::shared_ptr<Edge>> getEdges(); 
    void layout(); 

    private: 
    [...] 

}; 

class OgdfGmlReader : public GraphReader { 
    public: 
    OgdfGmlReader(std::string fileName); 
    virtual ~OgdfGmlReader(); 
    Graph* read();  
}; 

Avec la fonction de lecture() renvoyer le graphique valeur * comme suit:

Graph* OgdfGmlReader::read() { 

    [...] 

    OgdfGraph og; 
    og.setOgdfGraph(G); 
    Graph* graph = &og; 

    return graph; 
} 

Dans mon principal que je fais ce qui suit:

OgdfGmlReader tr = OgdfGmlReader("../data/lesmiserables.gml"); 
    GraphReader* gr = &tr; 
    Graph* graph = gr->read(); 

    graph->layout(); 

Le chargement des travaux de graphique, mais quand j'appelle la fonction de disposition sur le graphique, j'obtiens l'erreur suivante (sur l'exécution, elle compile):

pure virtual method called 
terminate called without an active exception 
Aborted (core dumped) 

Est-ce que ce problème vient du fait que je retourne le graphique et que je ne suis pas directement avant d'assigner la classe dérivée à sa classe parente comme avec le GraphReader? Je suis le plus confus car cela fonctionne pour le GraphReader mais pas pour le Graph (retourné par le GraphReader), car il est tout à fait le même pour ma compréhension.

Toute aide pour résoudre ce problème (tout en conservant éventuellement l'architecture d'héritage) est grandement appréciée!

Merci beaucoup d'avance!

Répondre

5

Le problème est en fonction Read:

L'instance de OgdfGraph og est variable locale qui est attribué à est renvoyé de fonction de lecture. S'il vous plaît noter que la variable og va sortir de la portée et supprimé une fois que la fonction Read a été exécutée. Par conséquent restera juste un pointeur vers Graph * sans aucune instance valide qui lui est allouée.

Vous pouvez le réparer en changeant OgdfGraph og comme OgdfGraph* pog = new OgdfGraph()

+2

Eh bien, dans ce cas, il se doit retourne un 'std :: shared_ptr' pour gérer correctement la mémoire et faire les changements appropriés partout. – Phil1970