在命令数据结构中使用联合

Use of union in a command data structure

本文关键字:命令 数据结构      更新时间:2023-10-16

我正在研究一个项目,在该项目中,我们将命令从上层进行下层。

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::variantboost::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 Talk:"使用lambdas实施变体访问"

您可以使用std ::变体和访问者模式。根据命令类型,您的访问者会做出不同的反应以处理有效载荷数据。

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

这提供了工会不提供的类型安全

使用工会作为"变体",尤其是出于"保存记忆"的目的,几乎总是表明设计差的迹象。您需要质疑设计/规范是否有意义。所以是的,有更好的方法:

如果这两个结构彼此无关,则将它们保留为2个单独的结构(或类)。与保存10-20字节的内存相比,无需紧密耦合的程序更重要。

否则,如果这两个结构确实有一些共同点,则将"参数"制作为一个抽象基类,其中包含结构的共同点。然后让"地址"answers" TSX"继承该基类。