尝试使用多态C ++时编译错误

时间:2014-09-11 05:40:47

标签: c++ polymorphism

我有一个基类模型,它在 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;语句,我会收到有关节点

标识符的语法错误

我很困惑这是什么问题?

2 个答案:

答案 0 :(得分:1)

您的问题与多态性无关,而与循环依赖性无关。 您不能拥有map<int, Node> nodes中声明的节点容器(例如Model),因为这会为Node的{​​{1}}创建依赖关系。但是,Model取决于Node(因为Model继承自Node)。

因此问题。

但是还有其他一些问题。

  1. 为什么Model中的add方法需要一个Node指针,然后继续复制(通过在地图中nserting * n)?谁拥有那个指针?它的寿命是多少?
  2. 为什么在Model类中全局定义了另一个Node地图?
  3. 为什么在各自的头文件中实现NodeNode类?由于ModelModel之间存在复杂的依赖关系,如果将其与标头混合,则无法实现模型解除引用Node对象。当您不使用模板时,您应该将声明和实现分开。
  4. NodeModel之间的关系是什么?你能说Node Node吗?这个层次结构对我来说很奇怪。
  5. 无论如何,这是一个应该工作的固定示例(虽然未经测试)。

    <强> 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,它会跳过这一行。这里它仍然不知道类节点的存在。因此,当您省略类节点行时,您将收到此错误。