Использование объединения в структуре данных команды

Я работаю над проектом, в котором мы передаем команды нижнему уровню от верхнего уровня.

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 ++)?

0

Решение

Ты хочешь 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»

1

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

Вы можете использовать std :: option и шаблон посетителя. В зависимости от типа команды ваш посетитель будет по-разному реагировать на обработку данных полезной нагрузки.

http://en.cppreference.com/w/cpp/utility/variant/visit

Это обеспечивает безопасность типов, которую профсоюзы не предлагают

-1

Использование союзов в качестве «вариантов», особенно с целью «экономии памяти», почти всегда свидетельствует о плохом дизайне. Вы должны подвергнуть сомнению, имеет ли смысл дизайн / спецификация. Так что да, есть гораздо лучшие способы:

Если эти 2 структуры не имеют ничего общего друг с другом, то оставьте их в виде 2 отдельных структур (или классов). Проектирование программ без жесткой связи намного важнее, чем сохранение 10-20 байт памяти.

В противном случае, если эти 2 структуры имеют что-то общее, сделайте «params» абстрактным базовым классом, который содержит все, что имеют общие структуры. Затем «address» и «tsx» наследуют этот базовый класс.

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