在单个结构中处理不同的数据类型

psv*_*hav 4 c++

我需要在VxWorks消息队列上发送一些信息.要发送的信息在运行时决定,并且可以是不同的数据类型.我正在使用这个结构 -

struct structData
{
  char m_chType;    // variable to indicate the data type - long, float or string
  long m_lData;     // variable to hold long value
  float m_fData;    // variable to hold float value
  string m_strData; // variable to hold string value
};
Run Code Online (Sandbox Code Playgroud)

我目前正在通过消息队列发送一个structData数组.

structData arrStruct[MAX_SIZE];
Run Code Online (Sandbox Code Playgroud)

这里的问题是结构中只有一个变量一次有用,另外两个变量无用.因此,消息队列不必要地重载.我不能使用联合,因为数据类型和值是必需的.我尝试使用模板,但它没有解决问题.我一次只能发送一个数据类型的结构数组.

template <typename T>
struct structData
{
  char m_chType;
  T m_Data;
}

structData<int> arrStruct[MAX_SIZE];
Run Code Online (Sandbox Code Playgroud)

是否有标准的方式来保存这些信息?

180*_*ION 7

我不明白为什么你不能使用工会.这是标准方式:

struct structData
{
  char m_chType;    // variable to indicate the data type - long, float or string
  union
  {
    long m_lData;         // variable to hold long value
    float m_fData;    // variable to hold float value
    char *m_strData; // variable to hold string value
  }
};
Run Code Online (Sandbox Code Playgroud)

通常,您打开数据类型,然后访问对该类型有效的字段.

请注意,您不能将联接string放入联合,因为该string类型是非POD类型.我已将其更改为使用指针,该指针可以是C以零结尾的字符串.然后,您必须考虑根据需要分配和删除字符串数据的可能性.

  • 你不能在`union`中有一个`string`(它有一个构造函数和析构函数) (6认同)

Yli*_*sar 6

你可以使用boost :: variant.


neu*_*uro 5

有许多方法可以处理不同的数据类型.除了union解决方案,您可以使用通用结构,如:

typedef struct
{
    char m_type;
    void* m_data;
} 
structData;
Run Code Online (Sandbox Code Playgroud)

这样您就知道了类型,并且可以将void*指针转换为正确的类型.这就像联合解决方案更多C而不是C++的做事方式.C++方式将是使用继承的东西.您可以定义基础"数据"类和使用继承来专门化数据.如果需要,您可以使用RTTI检查类型.

但正如您所说,您需要通过VxWork队列发送数据.我不是专家,但如果这些队列是OS实时队列,所有以前的解决方案都不是好的.你的问题是,你的数据具有可变长度(尤其是字符串),你需要通过一个队列,可能要求像固定长度datastruct这datastruct的实际长度给他们.

根据我的经验,处理这个问题的正确方法是将数据序列化为缓冲类/结构.通过这种方式,您可以优化大小(仅序列化所需的大小),并且可以通过队列发送缓冲区.

要序列化,您可以使用类似于1字节的类型,然后使用数据.要处理可变长度数据,可以使用1到n个字节来编码数据长度,因此可以反序列化数据.

对于一个字符串:1个字节来编码类型(0x01 = string,...)2个字节来编码字符串长度(如果你需要少于65536个字节)n个数据字节

所以字符串"Hello"将被序列化为:

0x00 0x00 0x07 0x65 0x48 0x6c 0x6c
Run Code Online (Sandbox Code Playgroud)

您需要一个缓冲类和一个序列化/反序列化器类.然后你做的事情如下:

serialize data
send serialized data into queue
Run Code Online (Sandbox Code Playgroud)

而在另一边

receive data
deserialize data
Run Code Online (Sandbox Code Playgroud)

我希望它有所帮助,我没有误解你的问题.如果VxWorks队列不是我想的那样,那么序列化部分就太过分了......