Я получаю эту ошибку при работе с рядом классов, включая друг друга:
error: expected class-name before '{' token
Я вижу, что происходит, но я не знаю, как правильно это исправить. Вот абстрактная версия кода:
хиджры
#ifndef A_H_
#define A_H_
#include "K.h"
class A
{
public:
A();
};
#endif /*A_H_*/
a.cpp
#include "A.h"
A::A() {}
B.h
#ifndef B_H_
#define B_H_
#include "A.h"
class B : public A
{ // error: expected class-name before '{' token
public:
B();
};
#endif /*B_H_*/
B.cpp
#include "B.h"
B::B() : A() {}
J.h
#ifndef J_H_
#define J_H_
#include "B.h"
class J
{
public:
J();
};
#endif /*J_H_*/
J.cpp
#include "J.h"
J::J() {}
K.h
#ifndef K_H_
#define K_H_
#include "J.h"
class K : public J
{ // error: expected class-name before '{' token
public:
K();
};
#endif /*K_H_*/
K.cpp
#include "K.h"
K::K() : J() {}
main.cpp
#include "A.h"
int main()
{
return 0;
}
Начиная с main.cpp , я могу определить, что это то, что видит компилятор:
#include "A.h"
#ifndef A_H_
#define A_H_
#include "K.h"
#ifndef K_H_
#define K_H_
#include "J.h"
#ifndef J_H_
#define J_H_
#include "B.h"
#ifndef B_H_
#define B_H_
#include "A.h"
class B : public A
{ // error: expected class-name before '{' token
Итак, определение A не является полным, когда мы достигаем B . Мне сказали, что иногда вам нужно использовать предварительное объявление, а затем переместить оператор # include в файл .cpp , но мне не повезло с этим. Если я попробую что-нибудь подобное, я просто получу дополнительную ошибку:
error: forward declaration of 'struct ClassName'
Я думаю, может быть, я просто не делаю вещи в нужных местах. Может кто-нибудь показать мне, как получить этот код для компиляции? Большое спасибо!
Edit: я хочу отметить, что это просто абстрактная версия реального кода. Я понимаю, что нет никаких ссылок на K в A или B в J , но есть в реальном коде, и я чувствую что они абсолютно необходимы. Возможно, если я дам краткое описание реальных классов, кто-то может помочь мне реструктурировать или исправить мой код.
Класс A - это абстрактный класс узлов, который действует как интерфейс для узлов в графе. Класс B является одной из нескольких реализаций A . Точно так же класс J является абстрактным классом Visitor, а K является соответствующей реализацией. Вот код с немного большим контекстом:
A.h (абстрактный узел)
#ifndef A_H_
#define A_H_
#include "K.h"
class K;
class A
{
public:
A();
virtual void accept(const K&) const = 0;
};
#endif /*A_H_*/
a.cpp
#include "A.h"
A::A() {}
B.h (бетонный узел)
#ifndef B_H_
#define B_H_
#include "A.h"
class K;
class B : public A
{ // error: expected class-name before '{' token
public:
B();
virtual void accept(const K&) const;
};
#endif /*B_H_*/
B.cpp
#include "B.h"
B::B() : A() {}
void B::accept(const K& k) const { k.visit(this); }
Дж.ч (Абстрактный посетитель)
#ifndef J_H_
#define J_H_
#include "B.h"
class B;
class J
{
public:
J();
virtual void visit(const B*) const = 0;
};
#endif /*J_H_*/
J.cpp
#include "J.h"
J::J() {}
Кч (Конкретный посетитель)
#ifndef K_H_
#define K_H_
#include "J.h"
class B;
class K : public J
{ // error: expected class-name before '{' token
public:
K();
virtual void visit(const B*) const;
};
#endif /*K_H_*/
K.cpp
#include "K.h"
K::K() : J() {}
void K::visit(const B*) const {};
main.cpp
#include "A.h"
int main()
{
return 0;
}
Мне пришлось добавить некоторые предварительные объявления, чтобы некоторые дополнительные ошибки, которые появились (когда я добавил детали), исчезли. Некоторые из них могут не быть необходимыми или правильными.