如何避免前向声明错误?

Posted

技术标签:

【中文标题】如何避免前向声明错误?【英文标题】:How can I avoid forward declaration error? 【发布时间】:2017-11-04 04:37:51 【问题描述】:

我在 C++ 中得到了以下代码:

class Level;

class Node

  char letter;
  std::string path[2];
  Node *next;
  Level *nlevel;

  public:

    Node()
    
      path[0] = "";
      path[1] = "";
      next = NULL;
      nlevel = NULL;
    

    Node(char l, unsigned int h)
    
      letter  = l;
      path[0] = "";
      path[1] = "";
      next = NULL;
      nlevel = NULL;
      nlevel->height = h;
    

    virtual ~Node();
;

class Level

  std::list<Node> vnodes;
  unsigned int height;

  public:

    Level();
    virtual ~Level();
;

调用或声明类的正确方法是什么?我一直在阅读 this 并且我已经尝试将 class Level; 放在类 Node 之前,但我得到了一个前向声明错误,如果我将每个类分隔在不同的文件中以便稍后包含它,我无论如何都会得到一个错误,因为它们相互依赖,那么应该如何声明呢?

【问题讨论】:

你得到什么“前向声明错误”? 使用您发布的代码将class Level 放在Node 之前对我来说效果很好。 @Galik 无效使用不完整类型'class Level' 是你贴的代码造成的还是缺少一些代码? @Galik 基本上是因为我贴的代码。 【参考方案1】:

只有在使用前向声明类的指针时才能前向声明。由于您在nlevel-&gt;height = h; 使用Level 的成员,因此您必须更改类的定义顺序。这会起作用,因为Level 只包含一个指向Node 的指针。

因为heightLevel 的私有成员,所以您还必须将friend class Node; 添加到Level 类中。

   class Node;
   class Level
   
       friend class Node;
       std::list<Node> vnodes;
       unsigned int height;

       public:

       Level();
       virtual ~Level();
   ;

   class Node
   
       char letter;
       std::string path[2];
       Node *next;
       Level *nlevel;

       public:

       Node()
          
           path[0] = ""; 
           path[1] = ""; 
           next = NULL;
           nlevel = NULL;
          

       Node(char l, unsigned int h)
       
           letter  = l;
           path[0] = "";
           path[1] = "";
           next = NULL;
           nlevel = NULL;
           nlevel->height = h;
       

       virtual ~Node();
   ;

【讨论】:

有道理。我没有尝试这样做,因为我没有将任何 Node *node 放入我的班级级别。谢谢,罗伯特。【参考方案2】:

解决这个问题的方法是将Node的函数定义放在Level的类定义之后,这样编译器就有了完整的类型描述:

class Level;

class Node

  char letter;
  std::string path[2];
  Node *next;
  Level *nlevel;

  public:

    Node(); // put the definition after

    Node(char l, unsigned int h);

    virtual ~Node();
;

class Level

  std::list<Node> vnodes;
  unsigned int height;

  public:

    Level();
    virtual ~Level();
;

// put node's function definitions AFTER the definition of Level
Node::Node()

  path[0] = "";
  path[1] = "";
  next = NULL;
  nlevel = NULL;


Node::Node(char l, unsigned int h)

  letter  = l;
  path[0] = "";
  path[1] = "";
  next = NULL;
  nlevel = NULL;
  nlevel->height = h; // Now you have access problem

或者您可以将函数定义移动到单独的.cpp源文件中。

现在您遇到了一个新问题,nlevel-&gt;height = h; 正在尝试访问 Levelprivate 成员。

【讨论】:

以上是关于如何避免前向声明错误?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的前向引用或声明

类前向声明​​失败,没有递归包含

基础类消息是前向声明错误

不完整类型的无效使用,前向声明不起作用

我需要相互包含两个头文件,而不是使用前向声明导致“不完整类型”错误

循环依赖结构,使用前向声明时重新定义结构错误