C – head file cycle dependence

I am trying to use two classes to implement a tree structure: tree and node. The problem is, from each class I want to call another class’s function, so the simple forward declaration is Not enough.

Let’s look at an example:

In tree.h:

#ifndef TREE_20100118
#define TREE_20100118

#include
#include "Node.h"

class Tree
{
int counter_ ;
std::vector 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
//#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 */

Call tree:

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

This is just a simple example to illustrate the problem. So what I want is to call the Tree function from the Node object.

< p>Update #1: Thank you for your answer. I try to solve the problem like in Java, that is, using only one file per class. It seems that I have to start separating the .cpp and .h files…

Update #2: Below, according to the prompt, I also pasted the complete solution. Thank you, the problem is solved.

In the title, forward declare member functions:

class Node
{
Tree * tree_;
int id_;

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

In a separate .cpp file containing all required headers, define them:

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

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

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

etc

This also keeps the title readable, so it is easy to see the interface of the class at a glance.

p>

I am trying to use two classes to implement a tree structure: tree and node. The problem is that from each class I want to call the function of another class, so simple forward The declaration is not enough.

Let’s look at an example:

In tree.h:

#ifndef TREE_20100118 
#define TREE_20100118

#include
#include "Node.h"

class Tree
{
int counter_;
std::vector 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
//#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 * /

Call tree:

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

This is just a simple example to illustrate the problem. So what I want is to call the Tree function from the Node object.

Update# 1: Thank you for your answer. I try to solve the problem like in Java, that is, each class uses only one file. It seems that I have to start separating the .cpp and .h files…

Update #2 : Below, according to the prompt, I also pasted the complete solution. Thank you, the problem is solved.

In the title, forward declares the member function:

class Node
{
Tree * tree_;
int id_;

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

In a separate In the .cpp file, define them:

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

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

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

etc

This can also keep the title available Readability, so it is easy to see the interface of the class at a glance.

Leave a Comment

Your email address will not be published.