我一直在制作一个使用 Box2D 物理引擎的游戏,但我在堆栈指针 (ESP) 和多重继承方面遇到了一些奇怪的事情。我已经设法用最少的代码重现了它,而且似乎我声明要在多重继承中使用的类的顺序似乎决定了程序是否崩溃。
#include <iostream>
#include <string.h>
using namespace std;
class IPhysicsObject
{
public:
virtual void Collide(IPhysicsObject *other, float angle, int pos)=0;
};
class IBoardFeature
{
public:
IBoardFeature(){};
~IBoardFeature(){};
virtual bool OnAttach(int x){ return true; }
virtual bool Update(int x, float dt)=0;
};
/*
class CScorezone : public IBoardFeature, public IPhysicsObject // this breaks !!!
class CScorezone : public IPhysicsObject, public IBoardFeature // this works !!!
*/
class CScorezone : public IBoardFeature, public IPhysicsObject
{
public:
CScorezone(){}
~CScorezone(void){}
virtual bool Update(int x, float dt)
{
return true;
}
virtual void Collide(IPhysicsObject *other, float angle, int pos)
{
}
virtual bool OnAttach(int x){ return true; }
};
int main(int argc, char *argv[])
{
CScorezone *scoreZone = new CScorezone();
CScorezone *otherZone = new CScorezone();
void *voidZone = scoreZone;
IPhysicsObject *physZone = static_cast<IPhysicsObject*>(voidZone);
physZone->Collide(otherZone, 10, 1);
delete scoreZone;
delete otherZone;
// wait for user input
int x;
cin >> x;
return 0;
}
在调试模式下运行它会导致以下错误
运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是调用使用一种调用约定声明的函数和使用另一种调用约定声明的函数指针的结果。
当我进入以下代码行时:
physZone->Collide(otherZone, 10, 1);
我注意到它会进入 CScoreZone::OnAttach,而不是 CScoreZone::Collide。为什么是这样?当我更改 CScoreZone 的继承顺序时,它工作正常
class CScorezone : public IPhysicsObject, public IBoardFeature
我在 Windows XP 上运行 VS2005 SP2 (8.0.50727.768)。有任何想法吗?