Почему я получаю неполный тип при использовании прямого объявления вместо #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
Тогда некоторые классы состояний, которые все более или менее одинаковы, я просто перечислю один:
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
teststate.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;
, Это сработало, и мой код скомпилирован и запущен.
Затем в гос.ч я заменил #include "state_machine.h"
с предварительной декларацией class state_machine;
(вы можете увидеть, где я это закомментировал).
Но теперь я получаю ошибку error: invalid use of incomplete type 'class state_machine'
который я прокомментировал в коде testState1.cpp. Но я не уверен почему. Почему state_machine является неполным типом?
1 ответ
teststate.cpp
необходимо определение state_machine
; так включить state_machine.h
там.
"Incomplete" означает, что компилятор видел только объявление, class state_machine;
не полное определение. Вы можете делать различные вещи с неполным типом, такие как объявление указателей или ссылок. Но вы не можете вызывать функции-члены (как вы это делаете здесь) или вообще делать что-либо, что требует знания членов класса, без полного определения.