Создание библиотеки со списком неизвестных типов шаблонов

Некоторое время назад я начал создавать игры и наткнулся на стиль, который мне действительно нравится. Это называется компонентной архитектурой. Учебник предназначен для Objective-C, а не C ++, но я все равно включил ссылку:
http://www.raywenderlich.com/24878/introduction-to-component-based-architecture-in-games

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

#ifndef ENTITY_H
#define ENTITY_H

#include "HealthComponent.h"#include "MoveComponent.h"#include "PlayerComponent.h"#include "RenderComponent.h"
class Entity
{
public:
Entity();

HealthComponent* getHealth();
//Returns a reference to the object's health component
//If there is none, returns a null pointer

MoveComponent* getMove();
//Returns a reference to the object's movement component
//If there is none, returns a null pointer

PlayerComponent* getPlayer();
//Returns a reference to the object's player component
//If there is none, returns a null pointer

RenderComponent* getRender();
//Returns a reference to the object's render component
//If there is none, returns a null pointer

~Entity();
private:
HealthComponent* health;
MoveComponent* move;
PlayerComponent* player;
RenderComponent* render;
};

#endif //ENTITY_H

Поскольку моя библиотека будет содержать общие рамки, а не отдельные компоненты, этот метод больше не работает. Вместо этого я создал ComponentManager класс для управления моими компонентами. В настоящее время сущность выглядит так:

#ifndef ENTITY_H
#define ENTITY_H

#include "Component.h"#include "ComponentManager.h"#include <list>

class Entity
{
public:
Entity();
Entity(ComponentManager const & cmanager);
template <T>
T* getComponent();
//Returns the first component of the specified type
//If there is none, returns NULL

template <T>
T* getComponent(int i);
//Returns the ith component of the specified type
//If the component does not exist, returns NULL

template<T>
int getComponentCount();
//Returns the number of components of the specific type that the
//entity contains

template <T>
int addComponent(T &component);
//Adds a component of the specified type to the class. If a component of the
//class already exists, the component is assigned a number, and the number is returned.
//If no components of the class exist, 0 is returned

~Entity();
private:
int eid;
std::list<ComponentReference> components;
ComponentManager * manager;
};

#endif //ENTITY

Я еще не определил эти функции, поэтому я не включил файл имплиментации.

ComponentReference struct просто представляет собой набор целых и строк, используемых для определения местоположения конкретного компонента. Сущность будет передавать ComponentReference к шаблонной функции в manager, который будет искать его внутренний список для конкретного объекта. И есть кирпичная стена. Я не знаю, как бы я создал список, содержащий неизвестное количество объектов разных неизвестных типов. Они получены от родителей Component класс, но все они содержат разные функции и переменные-члены. Я пытался использовать массив указателей и приведение типов, но через три часа я сдался, когда прочитал, что чрезмерная зависимость от приведения типов является показателем плохо написанного кода.

Я пытался использовать контейнеры STL, но им нужен только один тип, так что, очевидно, они не будут работать
(C ++ std :: vector с указателями на шаблонный класс)

Я видел кое-что о оболочках, но из того, что я прочитал, они работают только с функциями 🙁c ++ хранит указатель на функцию-член неизвестного класса) Если они могут быть использованы для решения моей проблемы, пожалуйста, объясните, как они работают (я никогда не слышал о них до сегодняшнего дня)

Так как это мой первый вопрос, не стесняйтесь оставлять отзывы. Я провел исследование, но если это дубликат, извините. Я не новичок в C ++, но я также не эксперт, и это большой язык, поэтому я могу попросить разъяснений. Заранее спасибо!

1

Решение

Задача ещё не решена.

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

Других решений пока нет …