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

标签 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));
    ...
}

这是一种有效且明智的继承方式吗?我问的原因是因为我遇到了模糊的运行时崩溃......没有分配任何动态内存。昨晚我在向 GameData(虚拟或非虚拟)添加 2 个成员函数时发生崩溃,然后当我慢慢添加它们时它消失了(首先是 1 个非虚拟,然后是 1 个虚拟,然后是 2 个非虚拟等)。

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

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

MinGW + 快板

最佳答案

按值传递时会发生切片。如果你的基类型是抽象的(有纯虚函数),切片就不会发生;编译器会提示。 (切片发生在复制对象时,但仅复制基类。)

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

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

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

关于c++ - 这种继承结构是否存在切片问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6042433/

相关文章:

c++ - 如何在一组迭代器上调用 `find`,通过迭代器指向的内容进行查找?

c++ - 逐层遍历和打印二叉树

javascript - 引用基类中的对象时的继承

java - 如何从另一个继承类调用 super 构造函数?

c++ - 为什么不接受使用概念的此类特化?

c++ - 从c++中的一行字符串中提取数字

c++ - 时间和基准

Java/安卓 : Return a class name through a method

javascript原型(prototype)继承混淆

java - 是否可以在不创建实例的情况下检查一个类是否在java中扩展另一个类?