头文件之间的循环依赖
Posted
技术标签:
【中文标题】头文件之间的循环依赖【英文标题】:Cyclic dependency between header files 【发布时间】:2011-01-06 12:56:33 【问题描述】:我正在尝试实现具有两个类的树状结构:Tree
和 Node
。问题是我想从每个类中调用另一个类的函数,所以简单的前向声明是不够的。
我们来看一个例子:
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 */
调用树:
#include "Tree.h"
...
Tree t;
t.start();
这只是一个简单的例子来说明问题。所以我想要的是从Node
对象调用Tree
的函数。
更新 #1: 感谢您的回答。我试图像在 Java 中那样解决这个问题,即每个类只使用一个文件。看来我得开始分离 .cpp 和 .h 文件了……
更新 #2: 在下面,按照提示,我也粘贴了完整的解决方案。谢谢,问题解决了。
【问题讨论】:
【参考方案1】:在头文件中,前向声明成员函数:
class Node
Tree * tree_;
int id_;
public:
Node(Tree * tree, int id);
~Node();
void hi();
;
在包含所有必需标头的单独 .cpp 文件中,定义它们:
#include "Tree.h"
#include "Node.h"
Node::Node(Tree * tree, int id) : tree_(tree), id_(id)
tree_->incCnt();
Node::~Node()
tree_->decCnt();
etc
这也有保持你的标题可读的效果,所以很容易一目了然地看到一个类的接口。
【讨论】:
【参考方案2】:按照提示,这里是完整的解决方案。
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】:Tree
的定义需要Node
的定义,但反之则不然,因此您的前向声明是正确的。
您所要做的就是从Node
类主体中删除需要完整定义Tree
的任何函数的定义,并在.cpp
文件中实现它们,其中两个类的完整定义都在范围内.
【讨论】:
【参考方案4】:你能把构造函数/析构函数放在 .cxx 文件中吗?您可以在其中包含 Tree.h。
【讨论】:
以上是关于头文件之间的循环依赖的主要内容,如果未能解决你的问题,请参考以下文章