2016-01-27 4 views
1

Зачем называть объединение, если компилятор всегда рассматривает объект как анонимный, независимо от того, называется ли объединение?В чем причина именования профсоюзов?

Моя реализация выглядит следующим образом:

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; 

Любые мысли о том, почему это так, или как я могу ss союз по имени?

+0

Каков тип 'id_in'? Почему вы ожидаете, что сможете присвоить вещь одного типа другому типу? –

+1

Эти typedefs никогда не были нужны в C++, даже на C++ 98 и все еще не в C++ 14. '_D' просто неправильно. – MSalters

ответ

1

Я не уверен, почему вы использовали бы союз в этом случае вообще. Обратите внимание, что размер структуры составляет 8 байтов (размер длинной длины) на моей 64-битной машине.

#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; 
} 

Если все, что вы храните в накидной MsgId это один идентификатор переменной длины (1 - 8) байт в зависимости от архитектуры) и у вас есть память не ограничивает переписать-структуру следующим образом:

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

Также я предлагаю прочитать this нить для подробного обсуждения использования союзов в C++.

-1

Там могут быть различные причины:

  • Там ограничения в оригинальной C компилятором, который не позволяет анонимным союзы. Другими словами, структура может использоваться как программами C, так и C++.
  • Возможно, вы захотите работать со всем соединением (перемещение, назначение и т. Д.), И это позволяет вам определить переменную таких типов.
-1

Потому что вы не используете анонимный союз в своем примере. Вы дали члену профсоюза вашей структуры имя, msgId, и у него есть члены. Вы не можете назначить непосредственно самому союзу, вы должны назначить член союза.

анонимный союз будет выглядеть следующим образом:

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

или

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

s s1.i2 = 5; 

Объединение в STRUCT с не имеет названия, и это члены обращаются напрямую.

ETA:

Если предположить, что переменная id_in является unsigned char, так как вы назначаете его без знака члена полукокса в примере, который работает, почему вы ожидали бы, чтобы это работало?

PDMSG_DESC ptMsg->hdr.msgId = id_in; 

ptMsg->hdr.msgId не типа unsigned char и не является неявное преобразование типа. ptMsg->hdr.msgId имеет тип _DMessageHeader::_msgId.

«Объединение - это особый тип класса, который может содержать только один из нестатических элементов данных за раз». (http://en.cppreference.com/w/cpp/language/union) Это тип класса, и вы не определили никаких операторов преобразования или конструкторов. Конечно, это не позволит назначить.

+0

Я не хочу анонимного союза. Я хочу иметь возможность ссылаться на объединение по имени, а не на его членов, так как его члены все равно занимают одинаковое пространство памяти. Кодирование более сложное, если мне нужно ссылаться на каждого члена по имени, а не на общую общую ссылку на имя объединения. –

+0

Тогда почему вы говорите об анонимных профсоюзах? Ничто в вашем примере не показывает компилятор, рассматривающий ваш союз как анонимный. Он показывает, что компилятор отказывается присваивать вещь одного типа вещи другого типа. –

2

Его тип вещь. Компилятор не может преобразовать int в объединение. Вы можете, однако, перегрузить оператор «=», чтобы сделать это.