为什么使用前向声明而不是 #include 时会出现不完整的类型
Why do I get incomplete type when using forward declaration instead of #include?
这里有state_machine.h:
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
// state machine classes
//#include "state_t.h"
class state_t;
class state_machine
{
public:
state_machine();
void change_state(state_t *newState);
void process_state(int data);
private:
state_t *_state;
};
#endif // STATE_MACHINE_H
这是state_t.h:
#ifndef STATE_T_H
#define STATE_T_H
#include <QByteArray>
#include <QDebug>
//#include "state_machine.h"
class state_machine;
class state_t
{
public:
state_t(QByteArray stateName);
virtual ~state_t();
virtual void processState(state_machine *sm, int input) = 0;
void defaultUnknownEventHandler(int event);
QByteArray name;
};
#endif // STATE_T_H
然后一些状态类,它们或多或少都是一样的,我只列出一个:
测试状态1.h:
#ifndef TESTSTATE1_H
#define TESTSTATE1_H
#include "state_t.h"
class testState1 : public state_t
{
public:
testState1();
void processState(state_machine *sm, int event);
};
#endif // TESTSTATE1_H
测试状态.cpp:
#include "teststate1.h"
#include "teststate2.h"
testState1::testState1() :
state_t("state1")
{
}
void testState1::processState(state_machine *sm, int event)
{
qDebug() << name << ": event" << event;
switch (event)
{
case 2:
{
// error: invalid use of incomplete type 'class state_machine'
sm->change_state(new testState2());
break;
}
default:
{
defaultUnknownEventHandler(event);
break;
}
}
}
问题:
我正在尝试整理我的代码,并使用前向声明使用最少量的标头包含(尤其是在头文件中)。您可以在state_machine类标头中看到我已经注释掉了#include "state_t.h"
并将其替换为前向声明class state_t;
。这有效,我的代码编译并运行。
然后,在 state.h 中,我用前向声明class state_machine;
替换了#include "state_machine.h"
(你可以看到我在哪里注释掉了它)。
但是现在我得到了错误error: invalid use of incomplete type 'class state_machine'
我在testState1.cpp代码中注释了该错误。但我不知道为什么。为什么state_machine是不完整的类型?
teststate.cpp
需要state_machine
的定义;所以包括state_machine.h
。
"不完整"意味着编译器只看到了一个声明,class state_machine;
,而不是一个完整的定义。可以使用不完整的类型执行各种操作,例如声明指针或引用。但是你不能调用成员函数(就像你在这里所做的那样),或者更一般地做任何需要了解类成员的事情,没有完整的定义。
相关文章:
- 将类型声明为类型模板参数的模板参数的一部分是否合法?
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*
- 如何使用自定义类型声明Arduino数组?
- 将函数参数类型声明为 auto
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 在没有标识符的情况下如何读取复杂的C++类型声明?
- 模板函数参数显式类型声明
- 使用指针遍历一系列基元类型声明?
- 字符类型声明和验证
- 使用本地类型声明的G lambda被使用但从未定义 - 确实是一个错误
- 为什么 c++ lambda 捕获不需要类型声明?
- 为什么没有"int"类型声明时输出不同?
- C++如何使用虚拟基类型声明全局静态分配的变量
- 我可以使用预处理器将一个类型声明替换为另一个类型声明吗?
- 如何将数据类型声明从.cpp文件传输到 .cu 文件
- C++17 枚举类型声明
- 条件类型声明
- 具有特定参数的特定构造函数的类型声明
- 我可以使用相同的名称为周围作用域中的类型声明成员类型别名吗
- 函数调用之前,C 类型声明