命名工会的原因是什么?

时间:2016-01-27 18:29:27

标签: c++ c++14 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;

它只允许我直接访问union成员,如下所示:

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

有关为什么会这样做的任何想法,或者我如何按姓名访问联盟?

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

我不确定为什么你会在这种情况下使用联盟。 请注意,我的64位计算机上结构的大小是8个字节(长的大小)。

#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 ++中使用联合。

答案 2 :(得分:-1)

可能有多种原因:

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

答案 3 :(得分:-1)

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

匿名联盟如下:

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

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

s s1.i2 = 5;

struct中的union没有名称,它的成员可以直接访问。

<强> ETA:

假设您的变量id_inunsigned char,因为您将其分配给有效的示例中的unsigned char成员,为什么您希望这个有效?

PDMSG_DESC ptMsg->hdr.msgId = id_in;

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

&#34; union是一种特殊的类类型,一次只能保存一个非静态数据成员。&#34; (http://en.cppreference.com/w/cpp/language/union)它是类类型,并且您没有定义任何转换运算符或构造函数。当然,它不会允许转让。