Zyklische Abhängigkeit zwischen Header-Dateien

Lesezeit: 3 Minuten

Zyklische Abhangigkeit zwischen Header Dateien
Jabba

Ich versuche, eine baumartige Struktur mit zwei Klassen zu implementieren: Tree und Node. Das Problem ist, dass ich von jeder Klasse eine Funktion der anderen Klasse aufrufen möchte, sodass einfache Vorwärtsdeklarationen nicht ausreichen.

Sehen wir uns ein Beispiel an:

Baum.h:

#ifndef TREE_20100118
#define TREE_20100118

#include <vector>
#include "Node.h"

class Tree
{
    int counter_;
    std::vector<Node> nodes_;

public:

    Tree() : counter_(0) {}

    void start() {
        for (int i=0; i<3; ++i) {
            Node node(this, i);
            this->nodes_.push_back(node);
        }
        nodes_[0].hi();    // calling a function of Node
    }

    void incCnt() {
        ++counter_;
    }

    void decCnt() {
        --counter_;
    }

};

#endif /* TREE_20100118 */

Knoten.h:

#ifndef NODE_20100118
#define NODE_20100118

#include <iostream>
//#include "Tree.h"

class Tree;    // compile error without this

class Node
{
    Tree * tree_;
    int id_;

public:

    Node(Tree * tree, int id) : tree_(tree), id_(id)
    {
//      tree_->incCnt();    // trying to call a function of Tree
    }

    ~Node() {
//      tree_->decCnt();    // problem here and in the constructor
    }

    void hi() {
        std::cout << "hi (" << id_ << ")" << endl;
    }

};

#endif /* NODE_20100118 */

Rufbaum:

#include "Tree.h"
...
Tree t;
t.start();

Dies ist nur ein einfaches Beispiel, um das Problem zu veranschaulichen. Was ich also will, ist das Aufrufen einer Funktion von Tree von einem Node Objekt.

Aktualisierung Nr. 1: Danke für die Antworten. Ich habe versucht, das Problem wie in Java zu lösen, dh mit nur einer Datei pro Klasse. Es scheint, dass ich anfangen muss, .cpp- und .h-Dateien zu trennen …

Aktualisierung Nr. 2: Unten habe ich den Hinweisen folgend auch die vollständige Lösung eingefügt. Danke, Problem gelöst.

Deklarieren Sie in den Headern die Memberfunktionen vorwärts:

class Node
{
    Tree * tree_;
    int id_;

public:
    Node(Tree * tree, int id);
    ~Node();
    void hi();
};

Definieren Sie sie in einer separaten .cpp-Datei, die alle erforderlichen Header enthält:

#include "Tree.h"
#include "Node.h"

Node::Node(Tree * tree, int id) : tree_(tree), id_(id)
{
  tree_->incCnt();
}

Node::~Node() 
{
  tree_->decCnt();
}

etc

Dies hat auch den Effekt, dass Ihre Kopfzeilen lesbar bleiben, sodass Sie die Benutzeroberfläche einer Klasse auf einen Blick sehen können.

Folgen Sie den Hinweisen, hier ist die vollständige Lösung.

Baum.h:

#ifndef TREE_20100118
#define TREE_20100118

#include "Node.h"
#include <vector>

class Tree
{
    int counter_;
    std::vector<Node> nodes_;

public:

    Tree();
    void start();
    void incCnt();
    void decCnt();
};

#endif /* TREE_20100118 */

Baum.cpp:

#include "Tree.h"
#include "Node.h"

Tree::Tree() : counter_(0) {}

void Tree::start()
{
    for (int i=0; i<3; ++i) {
        Node node(this, i);
        this->nodes_.push_back(node);
    }
    nodes_[0].hi();    // calling a function of Node
}

void Tree::incCnt() {
    ++counter_;
}

void Tree::decCnt() {
    --counter_;
}

Knoten.h:

#ifndef NODE_20100118
#define NODE_20100118

class Tree;

class Node
{
    Tree * tree_;
    int id_;

public:

    Node(Tree * tree, int id);
    ~Node();
    void hi();
};

#endif /* NODE_20100118 */

Node.cpp:

#include "Node.h"
#include "Tree.h"

#include <iostream>

Node::Node(Tree * tree, int id) : tree_(tree), id_(id)
{
    tree_->incCnt();    // calling a function of Tree
}

Node::~Node() {
    tree_->decCnt();
}

void Node::hi() {
    std::cout << "hi (" << id_ << ")" << std::endl;
}

Die Definition von Tree erfordert die Definition von Node aber nicht umgekehrt, also ist Ihre Vorwärtsdeklaration korrekt.

Alles, was Sie tun müssen, ist die Definition aller Funktionen zu entfernen, die eine vollständige Definition von erfordern Tree von dem Node Klassenkörper und implementieren sie in a .cpp Datei, in der die vollständigen Definitionen beider Klassen enthalten sind.

Können Sie die Konstruktor-/Destruktorkörper in einer .cxx-Datei verwenden? Sie könnten Tree.h dort einschließen.

.

618560cookie-checkZyklische Abhängigkeit zwischen Header-Dateien

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy