2014-12-17 3 views
4

Мое понимание объединения - все его значения выделяются по одному и тому же адресу памяти, а объем памяти равен наибольшему члену союза. Но я не понимаю, как мы будем их использовать. Это код, в котором использование соединения предпочтительнее в соответствии с The C++ Programming Language.Правильное использование союза

enum Type { str, num }; 

struct Entry { 
    char* name; 
    Type t; 
    char* s; // use s if t==str 
    int i; // use i if t==num 
}; 

void f(Entry* p) 
{ 
    if (p->t == str) 
      cout << p->s; 
    // ... 
} 

После этого Бьерн говорит:

Члены s и я никогда не могут быть использованы в то же время, так что пространство впустую. Его можно легко восстановить, указав, что оба должны быть членами объединения, например: union Значение { char * s; int i; }; язык не отслеживать, какой вид стоимости проводится объединением, поэтому программист должен сделать это: структура ввода { обугленного * имя; Тип t; Значение v; // используем v.s, если t == str; используйте v.i, если t == num }; void f (Entry * p) { if (p-> t == str) 10 cout v.s; // ...}

Может кто-нибудь объяснить полученный код накидной дальше? что на самом деле произойдет, если мы превратим это в союз?

+0

Союзов часто используется в сети при определении пакетов –

ответ

6

Предположим, у вас 32-разрядная машина с 32-разрядными целыми числами и указателями. Ваша структура может выглядеть следующим образом:

[0-3] name 
[4-7] type 
[8-11] string 
[12-15] integer 

Это 16 байт, но так как type (t в коде) определяет, какое поле действует, мы никогда не должны фактически хранить string и integer полей одновременно. Таким образом, мы можем изменить код:

struct Entry { 
    char* name; 
    Type t; 
    union { 
    char* s; // use s if t==str 
    int i; // use i if t==num 
    } u; 
}; 

Теперь раскладка:

[0-3] name 
[4-7] type 
[8-11] string 
[8-11] integer 

В C++, что вы присвоенный последнее является «действительным» членом союза, но нет никакого способа, чтобы узнать, какой из них по сути, поэтому вы должны хранить его самостоятельно. Этот метод часто называют «дискриминационным союзом», а «дискриминатором» является поле type.

Итак, вторая структура занимает 12 байт вместо 16. Если вы храните много из них или если они происходят из сети или диска, вам может быть интересно это. В противном случае это не очень важно. Структура

+0

К сожалению, я абсолютно не имею ни малейшего представления об этом бит/байтах вещи. если мне это неинтересно, мне не нужно правильно использовать профсоюзы? – morbidCode

+2

Исправить. Большинство проектов на C++ вообще не используют профсоюзы. В C++ есть множество функций, которые вам обычно не нужны. Другие примеры: facets, 'std :: ios_base :: xalloc()', размещение 'new' и многое другое! –

2

Для ниже союза,

union mix_types { 
    int l; 
    struct { 
    short hi; 
    short lo; 
    } s; 
    char c[4]; 
} mix; 

памяти будет, как: -

enter image description here

+0

«Структура памяти была бы такой: -» - не возражаете ли вы вставлять их в текст? Я не могу читать изображения. Благодарю. – morbidCode

+0

Пояснение уже предоставлено @ John, поэтому я просто использовал изображение. Вы можете связать это со своим объяснением – ravi

0

Другим способом вы можете использовать союзы, чтобы получить доступ к тем же данным с использованием различных типов.Пример может служить матричной структурой DirectX,

typedef struct _D3DMATRIX { 
    union { 
     struct { 
      float  _11, _12, _13, _14; 
      float  _21, _22, _23, _24; 
      float  _31, _32, _33, _34; 
      float  _41, _42, _43, _44; 

     }; 
     float m[4][4]; 
    }; 
} D3DMATRIX; 

Теперь вы можете сделать,

D3DMATRIX d; 
d._11 = 20; 
// Now the value of m[0][0] is 20 
assert(d._11 == m[0][0]); 
+1

Обратите внимание, что «безымянные» союзы и структуры на самом деле являются нестандартным расширением Microsoft Visual C++ (см. [C4201] (http://msdn.microsoft.com/en-us/library/c89bw853. ASPX)). Технически вам придется использовать '' struct D3DMATRIX {union D3DMATRIX1 {struct D3DMATRIX2 {...}; float m [4] [4]; }; '' быть стандартным C++. –

+1

Также обратите внимание, что шаблон, используемый устаревшим заголовком D3DXMath, написан для совместимости с C. C++ не требует построения '' typedef struct _X {...} X; ''. Вы можете просто выполнить '' struct D3DMATRIX {...}; '' –

Смежные вопросы