gpt4 book ai didi

c++ - 不完整类型/前向声明的无效使用

转载 作者:IT老高 更新时间:2023-10-28 22:37:19 25 4
gpt4 key购买 nike

我尝试查看 Stackoverflow 和 Google 上列出的类似问题,但它们主要处理模板,这不是我的情况。我在 Debian 测试 64 位上使用 GCC 4.4.5。
所以,我有两个类 - CEntity:

#ifndef CENTITY_H_INCLUDED
#define CENTITY_H_INCLUDED

#include "global_includes.h"

// game
#include "CAnimation.h"
#include "Vars.h"
#include "vector2f.h"
#include "Utils.h"

class CAnimation;

class CEntity
{
public:
CEntity();
virtual ~CEntity();

void _update(Uint32 dt);

void updateAnimation(Uint32 dt);

void addAnimation(const std::string& name, CAnimation* anim);
void addAnimation(const std::string& name, const CAnimation& anim);
void removeAnimation(const std::string& name);
void clearAnimations();

bool setAnimation(const std::string& name);

SDL_Surface* getImage() const;

const vector2f& getPos() const;
const vector2f& getLastPos() const;
F getX() const;
F getY() const;
F getLastX() const;
F getLastY() const;
SDL_Rect* getHitbox() const;
SDL_Rect* getRect() const;

F getXSpeed() const;
F getYSpeed() const;

void setPos(const vector2f& pos);
void setPos(F x, F y);
void setPos(F n);
void setX(F x);
void setY(F y);

void setHitboxSize(int w, int h);
void setHitboxSize(SDL_Rect* rect);
void setHitboxWidth(int w);
void setHitboxHeight(int h);

void setSpeed(F xSpeed, F ySpeed);
void setXSpeed(F xSpeed);
void setYSpeed(F ySpeed);

void stop();
void stopX();
void stopY();

void affectByGravity(bool affect);

void translate(const vector2f& offset);
void translate(F x, F y);

bool collide(CEntity& s);
bool collide(CEntity* s);

protected:
CAnimation* mCurrentAnimation;
SDL_Surface* mImage;

vector2f mPos;
vector2f mLastPos;
SDL_Rect* mHitbox; // used for collisions
SDL_Rect* mRect; // used only for blitting

F mXSpeed;
F mYSpeed;

bool mAffByGrav;

int mHOffset;
int mVOffset;

private:
std::map<std::string, CAnimation*> mAnims;
};

#endif // CENTITY_H_INCLUDED

和继承自CEntity的CPlayerChar:

#ifndef CPLAYERCHAR_H_INCLUDED
#define CPLAYERCHAR_H_INCLUDED

#include "global_includes.h"

// game
#include "CEntity.h"

class CEntity;

class CPlayerChar : public CEntity
{
public:
CPlayerChar();
virtual ~CPlayerChar();

virtual void update(Uint32 dt) = 0;

virtual void runLeft() = 0;
virtual void runRight() = 0;
virtual void stopRunLeft() = 0;
virtual void stopRunRight() = 0;

virtual void attack() = 0;
virtual void stopAttack() = 0;

virtual void attack2() = 0;
virtual void stopAttack2() = 0;

virtual void ground() = 0;
virtual void midair() = 0;

void jump();
void stopJump();

protected:
// looking right?
bool mRight;

bool mJumping;
bool mOnGround;
bool mGrounded;
};

#endif // CPLAYERCHAR_H_INCLUDED

当我尝试编译它时,GCC 会抛出这个错误:

CPlayerChar.h:12: error: invalid use of incomplete type ‘struct CEntity’
CPlayerChar.h:9: error: forward declaration of ‘struct CEntity’

我首先尝试了没有前向声明'class CEntity;'在第 9 行的 CPlayerChar.h 中,但它会改为抛出这个

CPlayerChar.h:12: error: expected class-name before ‘{’ token

所以前向声明必须在那里。此外,CEntity 显然是一个类,而不是一个结构。

最佳答案

您的头文件中有一个循环包含。
但是如果没有所有的头文件,我们将无法修复它。

我会从这里开始。

#include "CAnimation.h"

看看你的标题,你实际上并不需要这个。您只能通过引用或指针使用 CAnimation,因此您拥有的前向声明应该足够了。将包含移动到源文件中(即从标题中移出)。

下一个我要看的地方是:

#include "global_includes.h"

任何包含在头文件中的全局包含都最好非常简单。应该只包含简单类型并且不包含任何其他头文件(除非它们同样简单)。任何复杂的事情都会导致循环依赖的问题。

一般经验法则

头文件应该只包含它绝对需要的头文件。否则它们应该包含在源文件中。如果头文件定义了一个用作父类的类,那么您绝对需要一个头文件,您拥有该类的成员对象,或者您使用该类的参数对象。

我使用术语 object 来区分引用或指针。如果您使用这些,则不需要包含头文件。你只需要做一个前向声明。

关于c++ - 不完整类型/前向声明的无效使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6988924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com