简体   繁体   English

取消引用结构的并集结构

[英]De-referencing structure of union of structures

typedef struct
{
    int data1;
    float data2;
} packetType1;

typedef struct
{
     bool data1;
} packetType2;

typedef union
{
     packetType1 p1;
     packetType2 p2;
} packet;

struct
{
    int type;
    packet myPacket;
} message;

Now I make a message and pass the pointer to this message to a function. 现在,我创建一条消息并将该消息的指针传递给函数。 Inside this function I need to de-reference the message and take out the necessary data from it. 在此函数内部,我需要取消引用消息并从中取出必要的数据。

This data will depend on whether packet was filled with data of packetType1 type or of packetType2 type. 该数据将取决于数据包中是否填充了packetType1类型或packetType2类型的数据。 Inside message , the integer variable type can contain the value 1 or 2 only, telling that packet inside message is of type packetType1 or of type packetType2. 在message内部,整数变量类型只能包含值1或2,这表明内部message的数据包的类型为packetType1或packetType2类型。

I want to know if this is safe to do - 我想知道这样做是否安全-

packetType1 s1;
s1.data1 = 10;
s1.data2 = 22.22;


packetType2 s2;
s2.data1 = true; 

packet pack1; 
pack1.p1 = s1;

packet pack2;
pack2.p2 = s2;

message m1;
m1.type = 1;
m1.myPacket = pack1;

message m2;
m2.type = 2;
m2.myPacket = pack2;

eatPacket( &m1 );
eatPacket( &m2 );

void eatPacket( void *p )
{

    if( *(int*)p == 1)
    {
       message msg = *(message*)p
       cout << msg.myPacket.data1;
       cout << msg.myPacket.data2;
    }

    else if( *(int*)p == 2)
    {
       message msg = *(message*)p
       cout << msg.myPacket.data1;           
    }

}

Edit: ( For all those who are asking why I had used void* ) 编辑:(对于所有问我为什么使用void *的人)

These messages are sent from one process to other using posix message queue and then decoded there. 这些消息使用posix消息队列从一个进程发送到另一个进程,然后在此处进行解码。 Problem is that even this message structure could be different. 问题在于,即使此消息结构也可能不同。 Only thing I am sure is that the variable int type will always be there to guide me. 我唯一确定的是,变量int类型将始终存在以指导我。 Other part of the message might change. 消息的其他部分可能会更改。 So I had to make this function generic by making it accept a void * and then do decoding internally using the value provided by variable type. 因此,我必须通过使该函数接受void *使其通用,然后使用变量类型提供的值在内部进行解码。

Consider that someone makes a message like this now- 考虑到有人现在发出这样的消息-

struct
{
    int type;

    float data;
    bool moreData;
    int evenMoreData;

} newMessage;

For this new message it was decided that value for variable type would always be 3. 对于此新消息,已决定变量类型的值始终为3。

So in my eat function I will just add another clause like this 所以在我的eat函数中,我只会添加另一个像这样的子句

if( *(int*)p == 3)
{
       newMessage msg = *(newMessage*)p
       cout << msg.data;
       cout << msg.moreData;
       cout << msg.evenMoreData;
}

Will it still be safe to do so ? 这样做仍然安全吗? I hope this makes sense now ? 我希望这现在有意义吗?

It looks fine, but I'd rewrite eatPacket() like this: 看起来不错,但我会像这样重写eatPacket()

void eatPacket(const message& msg)
{

    if(msg.type == 1)
    {
       cout << msg.myPacket.data1;
       cout << msg.myPacket.data2;
    }

    else if(msg.type == 2)
    {
       cout << msg.myPacket.data1;           
    }

}

There's really no need for the void* gymnastics that I can see. 我所看到的,真的不需要void*体操。 If you really need msg to be a pointer you can modify the above in a straightforward way ( -> for . , etc). 如果您确实需要msg作为指针,则可以直接修改上述内容( ->表示.等)。

What would I do? 我该怎么办?

void eatPacket( message* msg )
{
    if(NULL == msg) return;

    if( message->type == 1 )
    {
       cout << msg->myPacket.data1;
       cout << msg->myPacket.data2;
    }
    else if(message->type == 2 )
    {
       cout << msg->myPacket.data1;           
    }

}

Is it safe to do your way? 这样行事安全吗? I don't really know. 我真的不知道 What is message? 什么是讯息?

I wouldn't do any of this. 我什么都不会做。 I would think it would be much cleaner to create an abstract BaseMessage class and then derive a class for the int payload and one for the bool payload. 我认为创建一个抽象BaseMessage类,然后为int有效负载派生一个类,然后为bool有效负载派生一个类,会更加干净。 Then you could have a virtual GetData() method. 然后,您可以有一个虚拟的GetData()方法。 When you pass in the pointer to the base class the correct virtual function will get invoked to return your data. 当您将指针传递给基类时,将调用正确的虚函数以返回您的数据。 A union is almost always a code smell that OO techniques can help with. 联合几乎总是一种OO技术可以帮助解决的代码味道。 A lot of how I would actually implement this depends on the variety of messages and how they eventually get used but hopefully you get the idea. 我实际上将如何实现这一目标取决于消息的种类以及消息最终的使用方式,但希望您能理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM