Шаблоны, полиморфизм, абстрактные указатели базового класса и приведение во время выполнения - PullRequest
1 голос
/ 06 апреля 2011

Я хочу внедрить шаблон Memento в игру для реализации контрольных точек.

У меня есть список указателей GameObject в игре.GameObject - это абстрактный класс, который реализуется такими классами, как StaticObject, AnimatedObject и т. Д. *

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

my (очень barebone, для целей отладки) Класс Memento:

template<class T>
class Memento
{
public:
    Memento() { }

    Memento(T data)
    {
        setData(data);
    }
    void setData(T data)
    {
    //wanting this function to do complex behaviour
    }

    T _state;
};

Я бы добавил в логику, чтобы различать, является ли T указателем или нет.

_state нужнобыть указателем копии фактического GameObject, а не просто копией самого указателя, так как это противоречит цели Memento.

Процесс, который я хотел бы сделать в шаблоне Memento:

1) Передать указатель на абстрактный базовый класс.

2) Определить тип дочернего классаон указывает на (во время выполнения).

3) Создайте новый дочерний класс в куче, указатель которого равен _state (из типа, полученного в 2).

4) Скопируйте данные.

Проблема, с которой я столкнулся, - 3. Кажется, я никак не могу получить правильный тип дочернего класса.

typeid (* data) и decltype (* data) возвращают ссылки на дочерние элементы.Если я пытаюсь использовать авто, это также ссылка.Очевидно, что я не могу использовать new со ссылкой в ​​качестве типа.

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

1 Ответ

4 голосов
/ 06 апреля 2011

Что вам нужно, так это «конструктор виртуальной копии», или клон, идиома.

class GameObject {
    ...
public:
    virtual GameObject* clone() = 0;
};

class StaticObject : public GameObject {
    ...
public:
    virtual StaticObject* clone() { return new StaticObject(*this); }
};

//..
...