Cyclic dependency between header files

耗尽温柔 提交于 2019-11-26 09:56:57

问题


I\'m trying to implement a tree-like structure with two classes: Tree and Node. The problem is that from each class I want to call a function of the other class, so simple forward declarations are not enough.

Let\'s see an example:

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

Calling Tree:

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

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

Update #1: Thanks for the answers. I tried to solve the problem like in Java, i.e. using just one file per class. It seems I will have to start separating .cpp and .h files...

Update #2: Below, following the hints, I pasted the complete solution too. Thanks, problem solved.


回答1:


In the headers, forward declare the member functions:

class Node
{
    Tree * tree_;
    int id_;

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

In a separate .cpp file that includes all the 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 has the effect of keeping your headers readable, so it is easy to see a class's interface at a glance.




回答2:


Following the hints, here is the complete solution.

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_;
}

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



回答3:


The definition of Tree requires the definition of Node but not the other way around so your forward declaration is correct.

All that you have to do is removed the definition of any functions that require a full definition of Tree from the Node class body and implement them in a .cpp file where full definitions of both classes are in scope.




回答4:


Can you but the constructor/destructor bodies in a .cxx file? You could include Tree.h there.



来源:https://stackoverflow.com/questions/2089056/cyclic-dependency-between-header-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!