2010-01-18 14 views
8

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, also sind einfache Vorwärtsdeklarationen nicht genug. Nehmen wir ein Beispiel sehen:zyklische Abhängigkeit zwischen Header-Dateien

Tree.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 */ 

Node.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 */ 

Aufruf Baum:

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

Dies ist nur ein einfaches Beispiel zur Veranschaulichung des Problems. Ich möchte also eine Funktion von Tree aus einem Node-Objekt aufrufen.

Update # 1: Danke für die Antworten. Ich habe versucht, das Problem wie in Java zu lösen, d. H. Mit nur einer Datei pro Klasse. Es scheint, ich muss beginnen zu trennen .cpp und .h Dateien ...

Update # 2: Unten, nach den Hinweisen, klebte ich auch die komplette Lösung. Danke, Problem gelöst.

Antwort

5

In den Headern, nach vorne erklären die Mitgliederfunktionen:

class Node 
{ 
    Tree * tree_; 
    int id_; 

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

In einem separaten CPP-Datei, die alle erforderlichen Header enthält, definieren sie:

#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 die Wirkung von Halten Sie Ihre Header lesbar, so dass es leicht ist, die Oberfläche einer Klasse auf einen Blick zu sehen.

0

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

1

Die Definition von Tree erfordert die Definition von Node, aber nicht umgekehrt, damit Ihre Forward-Deklaration korrekt ist.

Alles, was Sie tun müssen, ist die Definition aller Funktionen entfernt, die eine vollständige Definition der Tree aus den Node Klasse Körpern benötigen und sie in einer Datei .cpp implementieren, wo alle Definitionen beiden Klassen in ihrem Umfang sind.

2

Den Hinweisen folgend, hier ist die komplette Lösung.

Tree.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 */ 

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