Прокси-класс для полиморфного типа с использованием шаблонов

Это для «игрового движка» как немного практики программирования. Все мои GameObjects основаны на компонентах, где каждый компонент добавляет функциональность к своему родительскому GameObject, и все эти компоненты происходят от базового класса Component, который имеет виртуальные методы, делающие его полиморфным.

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

Мое решение состояло в том, чтобы в файле XML был узел в качестве подтверждения того, что компонент этого типа должен существовать, и, возможно, выдает исключение или другое соответствующее действие, если это не так.
Например.

<ComponentRequirement type="ComponentTransform">myTransformComponent</ComponentRequirement>

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

template <class T>
class ComponentRequirement {
public:

T* operator->() { (I chose the arrow operator because the CompReq class will never be referenced as a pointer)
return this->component;
}

//Other unrelated functions . . .

private:
T* component;
};

И все это прекрасно и прекрасно во время компиляции, потому что я могу просто сказать,

ComponentRequirement<ComponentTransform> req = ComponentRequirement("myComponentTransform");

Но мне нужно иметь возможность указать, какой тип шаблона будет вместо строки из строки при чтении XML. Я думал, что это может сделать хэш-карта, но я не думаю, что имя типа даже «равно» чему-либо другому, кроме удобочитаемая подсказка компилятора, поэтому я не смог использовать ее в качестве значения hashmap.

Можно ли это сделать и как я могу реализовать это? Вставка строкового литерала в «черный ящик магии» и получение чего-то, что можно использовать в качестве аргумента шаблона. И если это поможет, все, что будет значением «Т», является полиморфным.
Или есть лучшее решение моей проблемы. Он должен быть в состоянии действовать как любой компонент, который я вставил в него, и он должен быть различим во время выполнения.

РЕДАКТИРОВАТЬ 1:

В моих компонентах у меня есть функция чтения и записи. Если я прочту там требования к компоненту, то смогу убедиться, что шаблон имеет правильное значение, потому что каждый компонент является отдельным.
Затем я могу оценить требования с помощью виртуальной функции и нескольких функций в классе gameobject, чтобы убедиться, что это допустимая конфигурация. Это может решить проблему.

1

Решение

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

http://www.oodesign.com/factory-pattern.html

По сути, у вас была бы карта фабрик (объектов-создателей).

  1. Определите некоторый интерфейс верхнего уровня для ваших компонентов, например, IComponent.
  2. Определите фабричный класс для каждого компонента, который вы хотите сгенерировать и который имеет метод Create Instance. Я рекомендую, чтобы метод Create Instance был частью интерфейса, подобного IFactory.
  3. Во время настройки вашей программы создайте свою карту и назначьте фабрики для определенных ключей. ActorCreator [«MyComponent»] = new MyComponentFactory ();
  4. Когда вы хотите создать объект, считанный из узла XML, вы можете просто вызвать метод create instance на возвращенной фабрике для ключа. auto myComponent = ActorCreator [readXML] -> CreateInstance ();
  5. Теперь у вас есть субъект / компоненты, конкретный тип которых был определен во время выполнения, а не во время компиляции.
1

Другие решения


По вопросам рекламы [email protected]