Есть ли проблема с нарезкой в ​​этой структуре наследования? - PullRequest
2 голосов
/ 18 мая 2011

Я занимаюсь дизайном игр и решил, что мне нужна модель, ориентированная на данные ... один объект "игровых данных", который передается из подсистемы в подсистему и сам знает, как его следует рисовать, как должна работать физикасам, как входные данные от пользователя будут влиять на это и т. д.

Итак, я начал с объектов прослушивания "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 (виртуальных или не виртуальных), а затем они исчезли, когда я добавил их медленно (сначала 1 не виртуальный, затем 1 виртуальный, затем 2 не виртуальный и т. Д.).

Я читал что-то на SO (не помню, где это было сейчас) о наследовании и срезах.Я на самом деле не понял, но я делаю что-то опасное с моим наследованием, которое вызывает периодически возникающие ошибки во время выполнения?

Или я должен посмотреть на мой временной код, использующий QueryPerformanceCounter?

MinGW+ аллегро

1 Ответ

1 голос
/ 18 мая 2011

Нарезка происходит, когда вы передаете по значению.Если ваши базовые типы являются абстрактными (имеют чисто виртуальные функции), разделение не может происходить;компилятор будет жаловаться вместо этого.(Разрезание происходит, когда объект копируется, но копируется только базовый класс.)

Пока вы не пытаетесь использовать семантику значений (передача по значению и т. Д.), Ваша иерархия должна быть в порядке;В большинстве случаев в таких случаях я буду запрещать систематическое копирование, так как все происходит из boost::noncopyable, но в этом нет необходимости, если все базы являются абстрактными.

OneЕще одна особая проблема, на которую следует обратить внимание, это то, что все явные преобразования основаны на указателях или ссылках (не на значениях), и что они используют приведение новых стилей (dynamic_cast, в общем).Когда задействовано множественное наследование, приведение в стиле C может случайно оказаться reinterpret_cast, и код будет делать странные вещи после этого.

Кроме того, конечно, применяются обычные проблемы: не висящийуказатели и т. д. (Вы говорите, что у вас нет динамического выделения. Я нахожу это удивительным, если у вас есть полиморфные типы, которые обычно не должны поддерживать копирование.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...