我正在做一些游戏设计,并决定我想要一个以数据为中心的模型......一个“游戏数据”对象从子系统传递到子系统,并且知道自己应该如何绘制,物理应该如何操作本身,来自用户的输入将如何影响它等。
所以我开始使用“Listener”等对象,如“BaseRenderer”“BaseInputHandler”等:
class BaseRenderer
{
public:
virtual void Render(BITMAP *b) = 0;
};
class BaseInputHandler
{
public:
virtual int TakeInputs() = 0;
};
并创建了一个“GameData”对象,它继承自这些......
class GameData : public BaseRenderer, public BaseInputHandler, public BaseCalculator
{
public:
/* Virtual Overwrites: (each child of GameData will need to overwrite these!)
void Render(BITMAP *b);
int TakeInputs();
void Calculate();*/
};
然后每个子系统都有一个单例,它将对游戏数据执行各种操作(渲染,接受输入等)......
GameData gd; // Or inherited from GameData...
Input::System().Init();
...
while(loop) {
loop &= !(Input::System().GetInputs(&gd));
...
}
这是一种有效且明智的继承方式吗?我问的原因是因为我得到了模糊的运行时崩溃...没有分配任何动态内存。昨晚我遇到了将2个成员函数添加到GameData(虚拟或非虚拟)的崩溃,然后当我慢慢添加它们时它就消失了(先是1个非虚拟,1个是虚拟,2个是非虚拟等)。
我读了关于继承和切片的SO(不记得它现在在哪里)。我没有真正得到它,但我是否正在做一些危险的继承,这会导致间歇性的运行时错误?
或者我应该查看使用QueryPerformanceCounter的时序代码?
MinGW + allegro
答案 0 :(得分:1)
按值传递时会发生切片。如果您的基类型是抽象的(具有纯虚函数),则不会发生切片;编译器会抱怨。 (复制对象时会发生切片,但只复制基类。)
只要您不尝试使用值语义(按值传递等),您的层次结构应该没问题;在大多数情况下,在这种情况下,我会通过让所有内容都来自boost::noncopyable
来系统地禁止复制,但这并不是必需的,只要所有基础都是抽象的。
要注意的另一个特殊问题是所有显式转换都在指针或引用(而不是值)上,并且它们通常使用新样式转换(dynamic_cast
)。当涉及多重继承时,C风格的强制转换可能会意外地成为reinterpret_cast
,之后代码会做出奇怪的事情。
此外,当然,通常的问题适用:没有悬空指针等(你说你没有动态分配。如果你有多态类型,我通常不应该支持复制,我觉得这很令人惊讶。)