C++ 继承类时“无效使用不完整的类型“类树节点”

C++ 继承类时“无效使用不完整的类型“类树节点”,c++,C++,节点h: 树_节点.h: 一切看起来似乎都是正确的,但由于某些原因,我得到了错误“类树节点”的不完整类型的无效使用。我不明白为什么会这样 据我所知,这些问题的解决方案是将文件拆分为headers.h和source code files.cpp。已分割,但仍会收到此类错误。不能从不完整的类型继承。为了正确确定类的大小以及数据成员的偏移量,编译器在从树中继承时需要具有树节点的完整定义 但是通过放置类树节点;在已经包含了头之后,您可以隐藏编译器需要的定义。因此,只需删除line类树节点即可;应该使每一

节点h:

树_节点.h:

一切看起来似乎都是正确的,但由于某些原因,我得到了错误“类树节点”的不完整类型的无效使用。我不明白为什么会这样


据我所知,这些问题的解决方案是将文件拆分为headers.h和source code files.cpp。已分割,但仍会收到此类错误。

不能从不完整的类型继承。为了正确确定类的大小以及数据成员的偏移量,编译器在从树中继承时需要具有树节点的完整定义

但是通过放置类树节点;在已经包含了头之后,您可以隐藏编译器需要的定义。因此,只需删除line类树节点即可;应该使每一个编译都很好,除非你也遗漏了

正如正确指出的,您还需要删除tree_node.h中的include node.h,因为否则,在包含tree_node.h时传递给编译器的代码如下所示:

class node_base : public tree_node_t
{
public:
  node_base();
  ~node_base();
 };

 class node_base;
 class tree_node_t
 {
   tree_node_t();

   std::vector<node_base*> list;
   . . .
 };
无法编译,因为树节点的定义突然出现在试图从其继承的节点基的定义之后。

并且是正确的。我所要做的就是从tree_node.h中删除include

据我所知,解决这些问题的办法是把两个部门分开 文件转换为headers.h和源代码文件.cpp

将代码拆分成文件通常是首选的解决方案。练习至少对你有好处

但是,一般来说,仍然可以在单个文件中执行此代码,在本例中,只需一个转发声明

以下内容可编译、链接和运行,但作用很小:


不能使用不完整的类型进行派生。转发声明提供了不完整的类型,这就是它不起作用的原因;。然而,你对向量的正向解算是好的;从第二个文件中删除包含。很可能您希望树\u node\t从node\u base继承,因为您为什么不这样做?。你能详细说明一下你想要实现什么吗?@Markus说的:只要从tree_node.h中删除include就可以解决问题。如果文件递归地包含彼此,它怎么能编译得很好?@Rudolfs Bundulis I不正确?假设还有include-guard。这听起来似乎有道理,但现在我得到了一个新的错误:在'{'token.我该怎么办?@garbart如果你发布为tree_node.h内容的内容确实是该文件中的所有内容,那么你缺少include,并且在tree_node_t的定义后缺少分号。@Corristo,在这种情况下,这不是正确的陈述。他在包含node.h时是安全的,但当他包含node.h时则不是包括tree\u node.h,因为它会导致递归。我希望很明显,调用node\u base\t函数的任何tree\u node\t函数都必须是在tree\u node\t中声明的,并且在node\u base\t声明之后实现。
#include "node.h"

class node_base;
class tree_node_t
{
    tree_node_t();

    std::vector<node_base*> list;
    . . .
}
class node_base : public tree_node_t
{
public:
  node_base();
  ~node_base();
 };

 class node_base;
 class tree_node_t
 {
   tree_node_t();

   std::vector<node_base*> list;
   . . .
 };
#include <iostream>
using std::cout, std::flush, std::endl;

#include <vector>
using std::vector;

// in this ordering, the single forward suffices,
//   because all class pointers are a known size,
// and
//    this symbol (as yet) is only in the tree_node_t data, 
//    in the vector as a pointer

class node_base_t;


class tree_node_t
{
   // private data attributes
   vector<node_base_t*> list;

   // tbd ... other data

public:
   tree_node_t()  // default ctor
   // : list ctor is ok
      {
         cout << "\n  tree_node_t() " << flush;
      }

   ~tree_node_t() = default; // dtor

   // tbd ... more public functions

private:
   // tbd ... private functions
};


class node_base_t : public tree_node_t
{
   // private data
   // ... tbd - other data
public:
   node_base_t()  // tree_node_t default ctor is ok
      {
         cout << "\n  node_base_t() " << flush;
      }

    ~node_base_t() = default;

   // tbd ... more public functions
private:
   // tbd ... private functions
};

int main(int , char** )
{
   int retVal = -1;
   {
      node_base_t  nb;

      retVal = 0;
   }
   cout << "\n" << endl;

   return retVal;
}
  tree_node_t() 
  node_base_t()