命名工会的原因是什么?

What is the reason for naming unions?

如果编译器始终将对象视为匿名对象,无论是否命名联合,为什么要命名联合?

我的实现是这样的:

typedef struct _DMessageHeader {
    union _msgId {
        unsigned char ucMsgId;
        unsigned short usMsgId;
        unsigned long ulMsgId;
        unsigned long long ullMsgId;
    } msgId;
} DMSG_HDR, *PDMSG_HDR;

我希望能够像这样访问它,但是编译器抛出一个错误:

PDMSG_DESC ptMsg->hdr.msgId = id_in;

它只允许我像这样直接访问联合成员:

PDMSG_DESC ptMsg->hdr.msgId.ucMsgId = id_in;

关于这是为什么,或者我如何通过名称访问联合会的任何想法?

可能有多种原因:

  • 原始 C 编译器中存在不允许匿名联合的限制。换句话说,该结构可以被 C 和 C++ 程序使用。
  • 您可能想要使用整个联合(移动、分配等),这允许您定义此类类型的变量。

因为您没有在示例中使用匿名联合。您已为结构的联合成员命名 msgId,并且它有成员。不能直接赋值给工会本身,必须赋给工会成员。

匿名联合如下:

union {
    int i;
    char c;
};
i = 1;

struct s 
{
    int i1;
    union {
        int i2;
        char c2;
    };
};

s s1.i2 = 5;

struct s中的union没有名字,直接访问它的成员。

预计到达时间:

假设您的变量 id_in 是一个 unsigned char,因为您在示例中将其分配给了有效的 unsigned char 成员,您为什么期望它有效?

PDMSG_DESC ptMsg->hdr.msgId = id_in;

ptMsg->hdr.msgId 不是 unsigned char 类型,也不是隐式可转换类型。 ptMsg->hdr.msgId 属于 _DMessageHeader::_msgId.

类型

"A union is a special class type that can hold only one of its non-static data members at a time." (http://en.cppreference.com/w/cpp/language/union) 它是 class 类型,您没有定义任何转换运算符或构造函数。当然不允许赋值。

我完全不确定您为什么要在这种情况下使用 union。 请注意,在我的 64 位机器上,该结构的大小为 8 个字节(long long 的大小)。

#include <iostream>
using std::cout;
using std::endl;
typedef struct _DMessageHeader {
    union _msgId {
        unsigned char ucMsgId;
        unsigned short usMsgId;
        unsigned long ulMsgId;
        unsigned long long ullMsgId;
    }  msgId;
} DMSG_HDR, *PDMSG_HDR;

int main( int argc , char ** argv, char ** env)
{
    cout<<"sizof DMessageHeader"<<sizeof(DMSG_HDR)<<endl;
    return 0;
}

如果你在 union msgid 中存储的只是一个长度不同(1 - 8 个字节,具体取决于你的体系结构)的单个 id,并且你没有内存限制,请按以下方式重写你的结构:

typedef struct _DMessageHeader {
unsigned long long msgId;
} DMSG_HDR, *PDMSG_HDR;
DMSG_HDR hdr;
hdr.msgId = id_in;

我还建议阅读 this 线程以深入讨论在 C++ 中使用联合。

这是一种类型的东西。编译器无法将 int something 转换为 union。 但是,您可以重载“=”运算符来执行此操作。