Я работаю над проектом, в котором мы передаем команды нижнему уровню от верхнего уровня.
1. Обрабатывать одну команду за раз
мы используем следующую структуру данных.
struct Command{
//Different command types==> SEND / CREATE_TRANSACTION etc.
CommandType type;
//Associated parameters with every command
union{
struct{
string remote_ip;
uint16_t remote_port;
}address;
struct{
string transaction_id;
string transaction_details;
}tsx;
.
.
.
}params;
};
Мы передаем разные параметры для разных команд. Союз делает память эффективной.
Есть ли лучший способ (или шаблон дизайна) сделать это в C ++?
Другой.
2. Обработка нескольких команд в одном объекте команды.
Я могу сделать это следующим образом:
struct Command{
uint64_t flag; //ORed value of different command types
//parameters
struct{
string remote_ip;
uint16_t remote_port;
}address;
struct{
string transaction_id;
string transaction details;
}tsx;
};
Но это не эффективно для памяти.
Есть ли лучший способ создать несколько команд в одном объекте (в C ++)?
Ты хочешь std::variant
или же boost::variant
. Варианты — это безопасные типизированные союзы.
struct address {
string remote_ip;
uint16_t remote_port;
};
struct tsx {
string transaction_id;
string transaction details;
};
using command = std::variant<address, tsx>;
Пример использования:
command c0{tsx{/* ... */}};
std::visit(
overload(
[](const address&){ /* handle address case */ },
[](const tsx&) { /* handle tsx case */ }
),
c0
);
Для того, чтобы узнать, как реализовать overload
и аналогичные утилиты сопоставления с образцом, см. мой доклад ACCU 2017: «Реализация варианта посещения с использованием Lambdas»
Вы можете использовать std :: option и шаблон посетителя. В зависимости от типа команды ваш посетитель будет по-разному реагировать на обработку данных полезной нагрузки.
http://en.cppreference.com/w/cpp/utility/variant/visit
Это обеспечивает безопасность типов, которую профсоюзы не предлагают
Использование союзов в качестве «вариантов», особенно с целью «экономии памяти», почти всегда свидетельствует о плохом дизайне. Вы должны подвергнуть сомнению, имеет ли смысл дизайн / спецификация. Так что да, есть гораздо лучшие способы:
Если эти 2 структуры не имеют ничего общего друг с другом, то оставьте их в виде 2 отдельных структур (или классов). Проектирование программ без жесткой связи намного важнее, чем сохранение 10-20 байт памяти.
В противном случае, если эти 2 структуры имеют что-то общее, сделайте «params» абстрактным базовым классом, который содержит все, что имеют общие структуры. Затем «address» и «tsx» наследуют этот базовый класс.