Лучшее решение вашего вопроса зависит в основном от ваших случаев использования. Я вижу два основных случая использования:
- Вы хотите представить «функцию» из «устройства», так что вы можете достичь читаемого кода при манипулировании, что «устройства» из вашего кода. Например, устройство MediaPlayer имеет операции воспроизведения, остановки, паузы. Но вы упустили возможность просто добавлять функции-члены к вашему объекту «устройство», например Play(), потому что вы хотите повторно использовать свой игровой код для другого устройства, например, тюнерного устройства. Кроме того, вы хотите применить операции ко всем или к подмножеству этих «функций», например Enable()/Disable()/ToString()/Trigger(), Configure() ..., поэтому функция-член подход не является благоприятным.
- Вы хотите создать объектную модель документа, которая больше ориентирована на данные. Например, документ Xml.
Из того, что вы написали в своем вопросе, я предполагаю, что у вас есть случай использования 1 в виду. Тип Object
имеет все общие операции, в которых вы нуждаетесь.
Тем не менее, тогда существуют различия между всеми этими «функциями».
Для того, чтобы придерживаться своего простого подхода, вам нужно будет вручную настроить/настроить экземпляры объектов, которые могут в конечном счете оказаться раздражающим, но вряд ли можно избежать:
// Example of "annoying": If you have more than 1 "device",
// you have to write such a function for each of them.
// Also, there is that fishy bit with Object.Id - the association between
// your configuration data and your object you want to configure.
void ConfigureMenu(std::vector& menuItems, MenuConfigurationData& configData)
{
for(auto& menuItem : menuItems)
{
menuItem.Configure(configData[menuItem.Id]); // spoiler!
}
}
Также , Я склонен думать, что даже сейчас у вас есть код, который не отображается в вашем вопросе, который настраивает ваши объекты.
Имея это в виду, вы можете избавиться от идеи написать 1 тип класса на «устройство» вручную. Следующее устройство/меню нужно будет обрабатывать одинаково, но с выделенным большим количеством кодировок.
Итак, мой совет для вас - избавиться от вашего class Menu
навсегда, чтобы абстрагировать вашу проблему и моделировать вашу проблему, а именно: Object - это ваша «функция», а устройство - это просто набор функций/объектов. Затем ваш class Menu
просто станет экземпляром, названным Menu.
typedef uint32_t FunctionId; // for example uint32_t...
typedef std::map<FunctionId,Object> Device; // aka. Menu.
Затем в функции конфигурации вы, скорее всего, в любом случае, вы передаете в экземпляре этой Device
карты и ваша функция конфигурации заполняет ее объект, правильно настроена.
// those enums are still specific to your concrete device (here Menu) but
// you can consider the time it takes writing them an investment which will
// pay off later when you write your code, using your functions.
// You assign the function id which is used in your meta-data.
enum class MenuFunctions : FunctionId { play = ..., title = ..., instructions, ... };
// "generic" configuration function.
// Does not only configure your Object, but also puts it inside the device.
void ConfigureDevice(Device& device, ConfigData& configData)
{ // ...
}
И позже в вашем коде, вы можете получить доступ к функциям, как это:
menu[MenuFunctions::play].Trigger();
Существуют альтернативные подходы и вариации этого, конечно. Например, если у вас есть ваши метаданные (данные конфигурации, описания устройств), вы можете прекратить кодирование всего этого вручную и вместо этого написать некоторый генератор кода, который выполняет эту работу за вас.
Ваша первая версия такого генератора может создать ваши функции конфигурации и перечисления для вас.
Со всем этим на месте использование «вложенных классов» становится просто вопросом создания коллекций экземпляров устройства. Теперь, поскольку все ваши устройства одного типа, вы можете создавать и подгруппировать их на досуге.
Вы считаете «std :: map»? Это ассоциативный контейнер, что означает, что вы можете ссылаться на объекты с помощью меню ["title"] 'where' "title" 'является' std :: string' – yizzlez
Вы можете создавать методы, которые являются ссылками в хорошо известных местах, или если это массив, было бы прямо связать их во время построения. –
Это может быть std :: map. –
BitTickler