Я предполагаю, что это из компиляции Sprite.cpp.
Sprite.cpp включает sprite.h, в который входит game.h вверху. Последний включает снова sprite.h, который ничего не делает из-за своей защиты включения или прагмы. Это означает, что на данный момент нет известного класса, называемого sprite - как в этой компиляции, он находится ниже.
Результирующий код (после предварительной обработки, перед компиляцией) будет выглядеть так:
class Game { Sprite *... };
class Sprite { ... };
Sprite::func() {};
По сути, это не легко исправить. Вам нужно сделать так, чтобы один из заголовков не зависел от другого, включаемого первым. Вы можете сделать это, каждый раз, когда вам не нужно содержимое класса, чтобы объявить его вперед вместо того, чтобы включать его.
class Game;
class Sprite {...};
и
class Sprite;
class Game { Sprite *...};
так что если вы сделаете это, а затем скомпилируете sprite.cpp, предварительно обработанный вывод будет выглядеть как
class Sprite;
class Game { Sprite *... };
class Sprite { ... };
Sprite::func() {};
который будет работать. Компилятору не нужно точно знать, что такое Sprite, когда вы объявляете указатель на него. Фактически, единственное время, когда вам нужна полная декларация, это когда:
- Вы используете членов класса
- Вы наследуете от класса
- Вы используете sizeof в классе
- Вы создаете экземпляр шаблона с ним
И это все. Их может быть больше, но они не будут частыми случаями, и вы не должны сталкиваться с ними так быстро. В любом случае, сначала используйте предварительное объявление, а если оно действительно не работает, то включите заголовок.