У меня есть еще один вопрос, вытекающий из моего предыдущий вопрос Что касается абстракций, у меня есть еще одна проблема, связанная с настройкой данных в событии после его создания.
При существующем положении вещей я могу создавать события любого типа и без проблем применять их данные (используя модифицированную версию шаблона разработки стратегии). Проблема в том, что в данный момент я должен передать событию его данные при его создании.
IEvent* newEvent = new SpeedEvent( eventID, interpolation, 50.0f );
или же
IEvent* newEvent = new AnimationEvent( eventID, interpolation, &newAnimation );
Этот метод хорош, когда я знаю, какие данные находятся при создании объекта, но во многих случаях я не буду знать, какие данные будут в экземпляре.
Что было бы идеально, было бы создать новое событие как таковое:
IEvent* newEvent = new SpeedEvent( eventID, interpolation );
А затем назначьте ему данные следующим образом:
eventManager->assignData( eventID, *unknown data type* );
Таким образом, я бы позволил объекту обрабатывать данные по-своему. Будем весьма благодарны за любые предложения относительно решения этой проблемы, однако я действительно хочу избегать использования шаблонов, если могу.
Мои текущие данные и структура объектов очень похожи на те, которые предложены в ответе на мой предыдущий вопрос.
Ты можешь использовать Boost.Any передавать неизвестные данные. На сайте-источнике вы просто используете присвоение, а на сайте-приемнике вы используете any_cast, чтобы восстановить свою ценность.
редактировать небольшой код:
просто используйте boost :: any as неизвестный тип данных и присвойте ему свои значения (с вашим конкретным типом). На той стороне, где вам нужен конкретный тип, вы используете any_cast.
class EventManager {
//...
public:
void asignData(std::size_t eventId, boost::any value);
boost::any getData(std::size_t eventId) const;
};
eventManager->assignData( eventId, 12); // assignes an int
eventManager->assignData( eventId, 12.0); // assignes an doubleint value1=boost::any_cast<int>(eventManager->getData(eventID)); // gets an int
double value2=boost::any_cast<double>(eventManager->getData(eventID)); // gets a double
Если у вас нет ограничений на данные, используйте старый добрый void *
как тип данных. Внутри бетонного манипулятора приведен к правильному типу, который известен внутри манипулятора.
Если вы хотите наложить ограничения на данные, определите интерфейс / базу, которая описывает ваши спецификации данных и наследует их для каждого из возможных конкретных типов данных. Отправьте данные производного типа вашему универсальному обработчику (который принимает указатель на базовый класс). Внутри обработчика вы можете использовать открытый интерфейс, который вы определили для данных, или просто привести к конкретному типу.