联盟正确用法

mor*_*ode 4 c++ c++11

我对union的理解是它的所有值都分配在相同的内存地址中,并且内存空间与union的最大成员一样大.但我不明白我们将如何实际使用它们.根据C++编程语言,这是一个使用联合的代码.

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;
     // ...
}
Run Code Online (Sandbox Code Playgroud)

在此之后Bjarne说:

成员s和i永远不能同时使用,因此浪费了空间.通过指定两者都应该是union的成员,可以很容易地恢复它,如下所示:union Value {char*s; int i; }; 该语言不会跟踪union所持有的值,因此程序员必须这样做:struct Entry {char*name; 输入t; 价值v; //如果t == str,则使用vs; 如果t == num},使用vi; void f(Entry*p){if(p-> t == str)cout vs; // ...}

谁能进一步解释生成的联合代码?如果我们把它变成一个联盟,会发生什么?

Joh*_*nck 6

假设你有一台32位机器,有32位整数和指针.您的结构可能如下所示:

[0-3] name
[4-7] type
[8-11] string
[12-15] integer
Run Code Online (Sandbox Code Playgroud)

这是16个字节,但由于type(t在您的代码中)确定哪个字段有效,我们永远不需要同时实际存储stringinteger字段.所以我们可以改变代码:

struct Entry {
  char* name;
  Type t;
  union {
    char* s;  // use s if t==str
    int i;    // use i if t==num
  } u;
};
Run Code Online (Sandbox Code Playgroud)

现在的布局是:

[0-3] name
[4-7] type
[8-11] string
[8-11] integer
Run Code Online (Sandbox Code Playgroud)

在C++中,无论你最近分配给联盟的"有效"成员,但是没有办法知道哪一个是内在的,所以你必须自己存储它.这种技术通常被称为"区分联合","鉴别器"是该type领域.

所以第二个结构需要12个字节而不是16个字节.如果你要存储很多字节,或者它们来自网络或磁盘,你可能会关心这个.否则,它并不重要.

  • 正确.大多数C++项目根本不使用联合.C++中有许多通常不需要的功能.其他例子:facet,`std :: ios_base :: xalloc()`,placement`new`等等! (2认同)