c++ - 为什么使用前向声明而不是#include 时会得到不完整的类型?

标签 c++ forward-declaration incomplete-type

这里我有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

然后是一些状态类,它们或多或少都是相同的,我只列出一个:

teststate1.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;
        }
    }
}

问题:

我正在尝试整理我的代码,并通过使用前向声明来使用最少量的 header 包含(尤其是在 header 文件中)。您可以在 state_machine 类 header 中看到我已注释掉 #include "state_t.h" 并将其替换为前向声明 class state_t;。这有效,我的代码编译并运行。

然后,在 state.h 中,我将 #include "state_machine.h" 替换为前向声明 class state_machine; (您可以看到我将其注释掉的位置)。

但现在我收到错误 error: invalid use of incomplete type 'class state_machine' 我已在 testState1.cpp 代码中对此进行了注释。但我不知道为什么。为什么 state_machine 是不完整类型?

最佳答案

teststate.cpp需要定义state_machine;因此,请在其中包含 state_machine.h

“不完整”意味着编译器只看到了声明,class state_machine;,而不是完整的定义。您可以使用不完整类型执行各种操作,例如声明指针或引用。但是,在没有完整定义的情况下,您无法调用成员函数(正如您在此处所做的那样),或者更一般地说,您无法执行任何需要了解类成员的操作。

关于c++ - 为什么使用前向声明而不是#include 时会得到不完整的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19702909/

相关文章:

C++/CLI 前向声明问题

指向不完整结构类型和后来的结构类型完成 VS 的 C 指针。指向未声明类型 T_t 和稍后类型 T_t 声明的指针

c++ - 类/结构中的内联语句

c++ - vector 中的成员类型是什么意思?

c++ - 在 C++ 中使用 std::addressof() 函数模板而不是使用 operator& 有什么好处吗?

c++ - 基于先前输入的同一行输入

c++ - 使用两个相同的 typedef 不好吗?如何避免?

c++ - 访问组合类c++的成员

c++ - 不完整类型的无效使用(对于指向原子整型变量的指针)

c++ - 具有 std::map 和 std::variant 的不完整类型