我知道这个问题在 stackoverflow 上已经被回答过很多次了,我一直在搜索它们,但仍然无法解决。这种情况下的问题可能是由于所谓的循环依赖关系造成的,我已经尝试了另一篇文章中提到的一些解决方案,例如前向声明或放入标头保护,但仍然不起作用。我不知道为什么只有 ItemComponent 文件会出现此错误,而其余文件都工作正常。
编辑:编译 InputController.hpp 文件时发生第 13 行错误:“错误:‘ItemComponent’未命名类型;您的意思是‘TileComponent’吗?”
这是文件,我使用 c++17 和 premake5:
ItemComponent.hpp
#pragma once
#include "Components.hpp"
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL.h>
#include "../Game.hpp"
#include "../TextureManager.hpp"
#include <map>
class ItemComponent : public Component
{
public:
int box;
int tWidth, tHeight;
int width , height;
int scale;
struct ToolInfo
{
int x;
int y;
SDL_Texture* tex;
};
std::map<int, ToolInfo> ToolMap;
std::map<std::string, int> ItemMap;
SDL_Rect bracket[2], src, dest;
SDL_Texture *tex;
int text_width;
int text_height;
SDL_Surface *surface;
SDL_Texture *textTex;
SDL_Rect textRect;
SDL_Color textColor = {27, 27, 27, 160};
TTF_Font *font;
std::string text = "Unequipped";
SpriteComponent* sprite;
ItemComponent()
{
// Toolbox pos
tWidth = 64;
tHeight = 64;
box = 2;
scale = 3;
// Tool render initialization
width = height = 16;
tex = TextureManager::LoadTexture("game/assets/Objects/Items/tools and meterials.png");
ToolInfo hoe = { x: width*2, y: height*0, tex: tex};
ToolInfo axe = { x: width*1, y: height*0, tex: tex};
ToolMap.emplace(1, hoe);
ToolMap.emplace(2, axe);
ItemMap.emplace("Hoe", 1);
ItemMap.emplace("Axe", 2);
// Text
font = TTF_OpenFont("game/assets/Font/UniversCondensed.ttf", 20);
}
~ItemComponent() {};
void RenderToolbox();
void RenderText();
void RenderUpdateToolbox(std::string item);
void UpdateText(std::string newText);
void init() override
{
// Toolbox pos
for (int i = 0; i < box; i++)
{
bracket[i].x = tWidth * (i+1) + (i * 10);
bracket[i].y = 25;
bracket[i].w = tWidth;
bracket[i].h = tHeight;
}
sprite = &entity->getComponent<SpriteComponent>();
}
void draw() override
{
RenderText();
RenderToolbox();
if (sprite->action.onHold)
{ RenderUpdateToolbox(sprite->action.name); }
for (int i = 0; i < box; i++)
{
src.x = ToolMap[i+1].x;
src.y = ToolMap[i+1].y;
src.w = width;
src.h = height;
tex = ToolMap[i+1].tex;
dest.x = bracket[i].x + 10;
dest.y = bracket[i].y + 10;
dest.w = width * scale;
dest.h = height * scale;
TextureManager::Draw(tex, src, dest, SDL_FLIP_NONE);
}
}
private:
};
#endif // TOOLCOMPONENT_HPP
输入控制器.hpp
#pragma once
#include "Components.hpp"
#include <SDL2/SDL.h>
#include <iostream>
#include "../Game.hpp"
class InputController : public Component
{
public:
TransformComponent *transform;
SpriteComponent *sprite;
ItemComponent *item; // Error occurred here ****
InputController() = default;
~InputController() {}
void init() override
{
item = &entity->getComponent<ItemComponent>();
transform = &entity->getComponent<TransformComponent>();
sprite = &entity->getComponent<SpriteComponent>();
}
// Codes....
void update() override;
void draw() override;
};
Compnents.hpp(包括所有标头)
#pragma once
#include "ECS.hpp"
#include "TransformComponent.hpp"
#include "SpriteComponent.hpp"
#include "ItemComponent.hpp"
#include "InputController.hpp"
#include "ColliderComponent.hpp"
#include "TileComponent.hpp"
您应该能够通过
解决问题#include
指令,直到在类的定义之后。这可以帮助避免出现以下情况:包含的标头需要当前标头中的类定义完整。根据问题中的信息,以下代码应该可以工作。请注意,由于缺乏有关
Component
定义位置的信息,我为此使用 Comp.hpp
。另外,我会忽略您未定义的类型的任何成员。
ItemComponent.hpp
#pragma once
#include "Comp.hpp" // parent class required at class definition
class SpriteComponent; // full type definition not needed for the body of the class
class ItemComponent : public Component
{
public:
...
SpriteComponent* sprite;
ItemComponent()
{
...
}
~ItemComponent() {};
void RenderToolbox();
void RenderText();
void RenderUpdateToolbox(std::string item);
void UpdateText(std::string newText);
void init() override;
{
}
void draw() override;
}
private:
};
#include "SpriteComponent.hpp" // required for the definitions of draw and init
inline void ItemComponent::init()
{
...
sprite = &entity->getComponent<SpriteComponent>();
}
inline void ItemComponent::draw()
{
...
if (sprite->action.onHold)
{ RenderUpdateToolbox(sprite->action.name); }
...
}
InputController.hpp
#include "Comp.hpp"
// pointers in the class body don't require the following types to be complete:
class ItemComponent;
class SpriteComponent;
class TransformComponent;
class InputController : public Component
{
public:
TransformComponent *transform;
SpriteComponent *sprite;
ItemComponent *item;
InputController() = default;
~InputController() {}
void init() override;
// Codes....
void update() override;
void draw() override;
};
// include definitions required in init
#include "ItemComponent.hpp"
#include "TransformComponent.hpp"
#include "SpriteComponent.hpp"
inline void InputController::init()
{
item = &entity->getComponent<ItemComponent>();
transform = &entity->getComponent<TransformComponent>();
sprite = &entity->getComponent<SpriteComponent>();
}