继承类时"invalid use of incomplete type ‘class tree_node_t’"

"invalid use of incomplete type ‘class tree_node_t’" when inheriting class

本文关键字:tree class node incomplete invalid use 继承 of type      更新时间:2023-10-16

node.h:

#include "tree_node.h"
class tree_node_t;
class node_base : public tree_node_t
{
public:
node_base();
~node_base();
};

tree_node.h:

#include "node.h"
class node_base;
class tree_node_t
{
tree_node_t();
std::vector<node_base*> list;
. . .
}

一切看起来都是正确的,但由于某种原因,我收到错误"无效使用不完整的类型'类tree_node_t'"。我不明白为什么会这样。

据我了解,这些问题的解决方案是将文件拆分为标头(.h(和源代码文件(.cpp(。分裂,但继续收到这样的错误。

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

但是,通过在已经包含标头之后放置class tree_node_t;,您可以隐藏编译器所需的定义。因此,只需删除行class tree_node_t;应该可以使每个编译都很好,除非您还缺少包含保护。

正如Rudolfs Bundulis正确指出的那样,您还需要删除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_t的定义出现在试图从它继承的node_base的定义之后。

natersoz和Markus是对的。我所要做的就是从tree_node.h中删除#include

据我了解,解决这些问题的方法是拆分 文件转换为标头 (.h( 和源代码文件 (.cpp(。

将代码拆分为文件通常是首选解决方案。 这至少对你来说是一件对你有益的事情。

但是,通常仍然可以在单个文件中执行此代码,在这种情况下,可以使用一个前向声明。

以下编译、链接和运行(但作用很小(:


#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()