我有一个基类模型,它在 Model.h 中声明并实现,其中包含了guard:
#ifndef Model_h
#define Model_h
#include <iostream>
#include <conio.h>
#include "Node.h"
#include <map>
using namespace std;
class Node;
class Model
{
public:
void add(Node*);
protected:
map<int, Node> nodes;
};
void Model::add(Node *n)
{
nodes.insert(make_pair(n->returnTag(),*n));
}
#endif
我想要一个子类节点 - 它在 Node.h 中声明并实现了包含保护 - 继承模型类像这样:
#ifndef Node_h
#define Node_h
#include <map>
#include <vector>
#include "Model.h"
class Node;
map<int, map<int, Node>> tnodeMap;
map<int, Node>::iterator nodeIter;
class Node:public Model
{
public:
Node();
int returnTag();
/*some code*/
};
/*implementation*/
#endif
但是当我尝试构建它时,我得到错误C2027未定义的类型&#39; Node&#39;
如果我在 Model.h中省略class Node;
语句,我会收到有关节点
我很困惑这是什么问题?
答案 0 :(得分:1)
您的问题与多态性无关,而与循环依赖性无关。
您不能拥有map<int, Node> nodes
中声明的节点容器(例如Model
),因为这会为Node
的{{1}}创建依赖关系。但是,Model
取决于Node
(因为Model
继承自Node
)。
因此问题。
但是还有其他一些问题。
Model
中的add方法需要一个Node指针,然后继续复制(通过在地图中nserting * n)?谁拥有那个指针?它的寿命是多少?Model
类中全局定义了另一个Node
地图?Node
和Node
类?由于Model
和Model
之间存在复杂的依赖关系,如果将其与标头混合,则无法实现模型解除引用Node对象。当您不使用模板时,您应该将声明和实现分开。Node
和Model
之间的关系是什么?你能说Node
是Node
吗?这个层次结构对我来说很奇怪。无论如何,这是一个应该工作的固定示例(虽然未经测试)。
<强> Model.h 强>
Model
<强> Model.cpp 强>
#ifndef Model_h
#define Model_h
#include <iostream>
#include <map>
#include <conio.h>
// We SHOULD NOT include Node.h in this file
class Node; // Forward declaration is enough
using namespace std;
class Model
{
public:
void add(Node*);
protected:
map<int, Node*> m_nodes;
};
#endif // Model_h
<强> Node.h 强>
#include "Model.h"
// In the implementation file we CAN NOW include Node.
#include "Node.h"
void Model::add(Node* n)
{
m_nodes.insert(make_pair(n->returnTag(), n));
}
答案 1 :(得分:0)
您的两个头文件彼此相互依赖。使一个头文件独立。
如果编译器尝试编译第一个 node.h ,它将在此文件中找到include model.h
。
所以它会跳转到 model.h 来编译它。在这里,它找到了 model.h 文件,但由于ifndef
,它会跳过这一行。这里它仍然不知道类节点的存在。因此,当您省略类节点行时,您将收到此错误。