这个继承结构有切片问题吗?

时间:2011-05-18 09:20:41

标签: c++ inheritance

我正在做一些游戏设计,并决定我想要一个以数据为中心的模型......一个“游戏数据”对象从子系统传递到子系统,并且知道自己应该如何绘制,物理应该如何操作本身,来自用户的输入将如何影响它等。

所以我开始使用“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

1 个答案:

答案 0 :(得分:1)

按值传递时会发生切片。如果您的基类型是抽象的(具有纯虚函数),则不会发生切片;编译器会抱怨。 (复制对象时会发生切片,但只复制基类。)

只要您不尝试使用值语义(按值传递等),您的层次结构应该没问题;在大多数情况下,在这种情况下,我会通过让所有内容都来自boost::noncopyable来系统地禁止复制,但这并不是必需的,只要所有基础都是抽象的。

要注意的另一个特殊问题是所有显式转换都在指针或引用(而不是值)上,并且它们通常使用新样式转换(dynamic_cast)。当涉及多重继承时,C风格的强制转换可能会意外地成为reinterpret_cast,之后代码会做出奇怪的事情。

此外,当然,通常的问题适用:没有悬空指针等(你说你没有动态分配。如果你有多态类型,我通常不应该支持复制,我觉得这很令人惊讶。)