我对union的理解是它的所有值都分配在相同的内存地址中,并且内存空间与union的最大成员一样大。但我不明白我们将如何实际使用它们。 根据{{3}},这是一个使用联合的代码。
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;
// ...
}
此后Bjarne说:
成员s和i永远不能同时使用,因此浪费了空间。通过指定两者都应该是union的成员,可以很容易地恢复它,如下所示: 联合价值{ char * s; int i; }; 该语言不会跟踪联合所持有的值,因此程序员必须这样做: struct Entry { char * name; 输入t; 价值v; //如果t == str,则使用v.s;如果t == num,请使用v.i. }; void f(条目* p) { if(p-> t == str) cout v.s; // ... }
任何人都可以进一步解释生成的联合代码吗?如果我们把它变成一个联盟,会发生什么?
答案 0 :(得分:6)
假设你有一台32位机器,有32位整数和指针。您的结构可能如下所示:
[0-3] name
[4-7] type
[8-11] string
[12-15] integer
这是16个字节,但由于type
(代码中为t
)确定哪个字段有效,我们永远不需要实际存储string
和{{1 }}字段同时。所以我们可以改变代码:
integer
现在的布局是:
struct Entry {
char* name;
Type t;
union {
char* s; // use s if t==str
int i; // use i if t==num
} u;
};
在C ++中,无论你最近分配的是&#34;有效的&#34;工会成员,但没有办法知道哪一个本质上,所以你必须自己存储它。这种技术通常被称为&#34;区分联盟&#34;,&#34;鉴别器&#34;是[0-3] name
[4-7] type
[8-11] string
[8-11] integer
字段。
所以第二个结构需要12个字节而不是16个字节。如果您要存储大量的字节,或者它们来自网络或磁盘,您可能会关心这一点。否则,它并不重要。
答案 1 :(得分:2)
对于以下联盟,
union mix_types {
int l;
struct {
short hi;
short lo;
} s;
char c[4];
} mix;
内存结构如下: -
答案 2 :(得分: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]);