C++ 这种继承结构是否存在切片问题?

C++ 这种继承结构是否存在切片问题?,c++,inheritance,C++,Inheritance,我正在做一些游戏设计,并决定我想要一个以数据为中心的模型。。。一个从一个子系统传递到另一个子系统的“游戏数据”对象,它知道自己应该如何绘制,物理应该如何对自己进行操作,用户的输入将如何影响它等等 所以我从“Listener”ish对象开始,比如“BaseRenderer”、“BaseInputHandler”等: 并创建了一个“GameData”对象,它继承了这些 class GameData : public BaseRenderer, public BaseInputHandler, pub

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

所以我从“Listener”ish对象开始,比如“BaseRenderer”、“BaseInputHandler”等:

并创建了一个“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));
    ...
}
这是一种有效且合理的继承方式吗?我问这个问题的原因是因为我遇到了模糊的运行时崩溃。。。不分配任何动态内存。昨晚,我在GameData中添加了两个成员函数(虚拟或非虚拟),导致崩溃,然后当我慢慢添加它们时,崩溃消失了(先是1个非虚拟,然后是1个虚拟,然后是2个非虚拟等等)

我读了一些关于继承和切片的东西(不记得它现在在哪里)。我并没有真正理解它,但我是否对我的继承做了一些危险的事情,导致了间歇性的运行时错误

或者我应该查看使用QueryPerformanceCounter的计时代码吗


MinGW+allegro

在传递值时发生切片。如果基类型是抽象的(具有纯虚拟函数),则无法进行切片;编译器将对此进行投诉。(复制对象时发生切片,但仅复制基类。)

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

另一个需要注意的特殊问题是,所有显式转换都在指针或引用(不是值)上,并且它们使用新样式转换(
dynamic\u cast
)。当涉及多重继承时,C风格的强制转换可能会意外地变成一个
重新解释\u强制转换
,然后代码会做一些奇怪的事情


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

我猜你的意思是切片而不是拼接。解释了切片。但我不认为这是你的问题。你在这里展示的看起来不错。你必须详细描述一下你经历过的碰撞。@Bingo,我觉得这样很好。你应该公布你遇到的崩溃或动态内存问题。切片,而不是拼接。如果您通过指针或引用传递对象,那么这可能不存在风险。如果按值传递,则会发生这种情况,派生类可能会转化为基类。可能是因为您忘记为基类定义虚拟析构函数(但可能您没有将其放在此处)。@Alexandre C.我只是将基类用作向任何编写“游戏数据”的人表达的一种方式对象需要编写哪些函数。。。但我在基层没有什么可破坏的。我应该仍然使用虚拟析构函数吗?我只是说我还没有动态分配。我目前的游戏数据只是一个盒子的坐标。。。这些只是从main()中堆栈上的GameData继承的类中的整数值。它最终会进行分配,但没有任何分配方式会导致崩溃。。。哦,谢谢你的回答:)
GameData gd; // Or inherited from GameData...
Input::System().Init();
...
while(loop) {
    loop &= !(Input::System().GetInputs(&gd));
    ...
}