у меня есть два класса Player и MapEditor , в классе Player я использую MapEditor, а в MapEditor я использую Player. Я забыл как называется это проблема но когда я пишу в Player.h , #include "MapEditor.h", а в MapEditor.h я пишу #include "Player.h", то у меня весь error list забит ошибками типо syntaxis error 'MapEditor' , undeclared identifer, также это мелочь конечно но подсветка синтаксиса в классах перестаёт работать. Кто нибудь знает в чем проблема?
TileMap.h -
#ifndef TILEMAP_H
#define TILEMAP_H
#include "Tile.h"
class MapEditor
{
private:
void clear();
float gridSizeF;
unsigned gridSizeU;
sf::Vector2f maxSizeWorldGrid;
sf::Vector2f maxSizeF;
sf::RenderWindow * window;
unsigned layers;
std::vector < std::vector < std::vector < Tile*> > > map;
sf::RectangleShape TileSet;
sf::RectangleShape collisionBox;
sf::Texture textureSheet;
std::string textureFile;
sf::Vector2i pixelPos;
sf::Vector2f pos;
void initTextures();
void initTileSet();
public:
MapEditor(sf::RenderWindow * window,std::string textureFile);
virtual ~MapEditor();
void addTile(const unsigned x, const unsigned y, const unsigned z, sf::IntRect& textureRect,const bool collision,const short type);
void removeTile(const unsigned x, const unsigned y, const unsigned z);
sf::Texture &getTextureSheet();
void saveToFile(const std::string filename);
void loadFromFile(const std::string filename);
void checkCollision(Player * player);
const sf::Vector2f & getMapSize() const;
const unsigned & getLayerCount() const;
const std::vector<std::vector<std::vector<Tile*> > >& getTiles() const;
void update(float time);
void render(sf::RenderWindow& window);
};
#endif // ! TILEMAP_H
Player.h -
#ifndef PLAYER_H
#define PLAYER_H
#include "Entity.h"
class Player {
protected:
AnimationManager anim;
float posX, posY, dx, dy;
float speed;
enum MovementDirection {
STAY,
LEFT,
RIGHT,
JUMP,
TOP,
DOWN
};
sf::Sprite sprite;
MovementDirection state;
bool playerOnGround;
bool life;
unsigned hp;
public:
Player(float x, float y, sf::Texture & texture, std::string anim_file);
virtual ~Player();
const bool& checkLife() const;
void movement(float time);
void checkCollision(float Dx,float Dy);
const sf::FloatRect& getRect() const;
virtual const sf::Vector2f& getPosition() const;
void update(float time);
void render(sf::RenderWindow * window);
};
#endif //CATCHONBUBBLE_PLAYER_H
Суть проблемы: при использовании директивы #include
компилятор вставляет код из включаемого файла туда, где эта директива прописана. Если у Вас используется такое взаимное включение, как описано в вопросе, возникает неявная рекурсия: один файл включает другой, который вновь включает первый, а тот, в свою очередь, снова включает второй и т.д. Это приводит к множественному переопределению всего, что объявлено в этих файлах.
Такая проблема обычно решается выполнением следующих шагов:
.h
-файлах, а реализацию всех методов вынести в одноимённые .c
/.cpp
-файлы.h
, а в .c
/.cpp
-файлах. Например, в файл X.cpp
написать #include"Y.h"
, а в Y.cpp
написать #include"X.h"
.h
-файлах) встречаются имена классов из включаемых файлов, необходимо прописать там class Название_класса;
, что даст понять компилятору, что этот класс объявлен где-то ещёТакже следовало бы добавить, #pragma once
в начале .h
-файлов. Это не спасает от представленной проблемы, но спасёт от множества потенциальных.
Меня такая инструкция не раз спасала от проблем, подобных описанной в вопросе.
В представленном коде пункт №1, по всей видимости, уже выполнен.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Код ошибок не вызывает, однако, при запуске кода - он даже не ждет пока пользователь введет значение и просто закрываетсяКак это исправить?...
Слева требуемы результат, справа как получается у меня: