[英]error C2504: base class undefined
我之前多次遇到这个错误并最终找到了解决方案,但是这个让我很难过。 我有一个由“Player”类继承的“Mob”类。 这是 Mob.h:
#pragma once
#include "PlayState.h"
#include "OmiGame/OmiGame.h"
#include "resources.h"
class PlayState;
class Mob
{
private:
int frames;
int width;
int height;
int time;
sf::Texture textureL;
sf::Texture textureR;
Animation animationL;
Animation animationR;
AnimatedSprite sprite;
bool moveLeft;
bool moveRight;
bool facingRight;
public:
void createMob(std::string l, std::string r, int frames, int width, int height, int time, int x, int y);
void updateMob(omi::Game *game, PlayState *state);
void drawMob(sf::RenderTarget &target);
void setLeft(bool b) { moveLeft = b; }
void setRight(bool b) { moveRight = b; }
bool isLeft() { return moveLeft; }
bool isRight() { return moveRight; }
sf::Vector2f getPosition() { return sprite.getPosition(); }
};
这是 Player.h,到目前为止它非常简单:
#pragma once
#include "OmiGame/OmiGame.h"
#include "PlayState.h"
#include "Mob.h"
#include "resources.h"
class PlayState;
class Mob;
const int playerFrames = 8;
const int playerWidth = 16;
const int playerHeight = 48;
const int playerTime = 50;
const int playerX = 200;
const int playerY = 200;
class Player : public Mob
{ //the error occurs at this line//
public:
Player();
void update(omi::Game *game, PlayState *state);
void draw(sf::RenderTarget &target);
};
而且,您可能会猜到,这是错误:
error C2504: 'Mob' : base class undefined player.h
我已经转发了声明的暴民,我希望修复了任何循环依赖。 请问有人可以帮我吗?
前向声明对class Player : public Mob
没有帮助,因为编译器需要完整的继承定义。
所以很可能你在 Mob.h 中包含的一个是引入 Player.h ,然后将 Player 置于 Mob 之前,从而触发错误。
我已经解决了类似的问题,我提出了解决方案并将其作为我的经验法则
解决方案/拇指规则
//File - Foo.h
#include "Child.h"
class Foo
{
//Do nothing
};
//File - Parent.h
#include "Child.h" // wrong
#include "Foo.h" // wrong because this indirectly
//contain "Child.h" (That is what is your condition)
class Parent
{
//Do nothing
Child ChildObj ; //one piece of advice try avoiding the object of child in parent
//and if you want to do then there are diff way to achieve it
};
//File - Child.h
#include "Parent.h"
class Child::public Parent
{
//Do nothing
};
不要将孩子包含在父类中。
如果您想知道在父类中拥有子对象的方法,请参考链接Alternative
谢谢
我知道这不是解决该问题的最佳方法,但至少对我有用。 您可以将所有其他包含在 cpp 文件中:
#include "OmiGame/OmiGame.h"
#include "PlayState.h"
#include "Mob.h"
#include "resources.h"
只是有同样的问题。 @TheUndeadFish 的回答很有帮助,但我花了一段时间才找到根本原因。 我将在下面分享一个导致此问题的示例场景以及我为追踪它而执行的步骤。
所以让我们假设我们有三个简单的类:
// a.h
#pragma once
#include "b.h"
#include "c.h"
class b;
class c;
class a {
b* field_b;
c* field_c;
public:
a();
};
a
取决于b
和c
。
// b.h
#pragma once
#include "a.h"
class a;
class b {
a* field_a;
public:
b();
};
b
循环依赖于a
(我正在通过前向声明解决这个问题)。
// c.h
#pragma once
#include "b.h"
class c : public b {
public:
c();
};
c
派生自b
。
实现文件也非常简单(只是为了简单起见,我将它们全部放在一个块中,但请记住,它们是三个单独的文件):
// a.cpp
#include "a.h"
a::a() { }
// b.cpp
#include "b.h"
b::b() { }
// c.cpp
#include "c.h"
c::c() { }
现在将它们添加到您的项目中,尝试编译,您将得到类似于以下错误的内容(我使用的是 Visual Studio):
1>Z:\test\ch(6,20): 错误 C2504: 'b': 基类未定义
所以我们已经知道问题在于,在特定的编译单元中,编译器在看到父类之前先看到子类。
我们如何证明这一点? 最简单的方法是使用消息 pragma 。
我在每个头文件中添加了两条消息,一条在顶部(在所有包含指令之前),另一条在类定义之前。 例如,这就是ch
现在的样子:
#pragma once
#pragma message("Top in: " __FILE__)
#include "b.h"
#pragma message("Before class in: " __FILE__)
class c : public b {
public:
c();
};
重建项目将显示以下输出:
重建开始...
1>----- 重建所有开始:项目:测试,配置:调试 x64 ------
1>a.cpp
// 编辑..
1>b.cpp
1>顶部:Z:\test\bh
1>置顶:Z:\test\ah
1>置顶:Z:\test\ch
1>上课前:Z:\test\ch
1>Z:\test\ch(6,20): 错误 C2504: 'b': 基类未定义
1>课前在:Z:\test\ah
1>上课前:Z:\test\bh
1>c.cpp
// 编辑..
1>生成代码...
1>完成构建项目“test.vcxproj”——失败。
==========全部重建:0成功,1失败,0跳过==========
请注意b.cpp
的编译单元(粗体)失败了,我们可以看到确切的位置和原因:编译器在看到c
的类定义之前先看到b
的类定义。
一个简单的解决方法是将#include "ah"
指令从bh
移动到b.cpp
。 重建项目,这一次编译器将按照所需的顺序查看类定义:
重建开始...
1>----- 重建所有开始:项目:测试,配置:调试 x64 ------
1>a.cpp
// 编辑
1>b.cpp
1>顶部:Z:\test\bh
1>上课前:Z:\test\bh
1>置顶:Z:\test\ah
1>置顶:Z:\test\ch
1>上课前:Z:\test\ch
1>课前在:Z:\test\ah
1>c.cpp
// 编辑
1>生成代码...
1>test.vcxproj->test.exe
==========全部重建:1成功,0失败,0跳过==========
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.