方案,最好使用union而不是struct

时间:2012-01-11 16:58:43

标签: c++ struct unions

有些人可以给我一些情况,在某些问题中使用union而不是struct是明智的吗?

由于

2 个答案:

答案 0 :(得分:4)

每当有数据瓶颈时使用联合是明智的,并且您有两个相互排斥但在同一数据结构中可用的数据。

假设我有两条具有相同数据的消息,除了两条数据在它们之间相互排斥,并且大小接近(32位int和4字节数组)。我可以将两者结合起来,并且消息可以共享数据结构,而不会增加它们不会使用的大小。

注意问题:

将来数据可能不会互相排斥。 初始化互斥数据。 为两个消息重用相同的数据实例(您需要确保切换互斥数据,或者接收者处理垃圾数据)。

使用联合来引用具有不同类型定义的相同数据是未定义的行为。所以:

  • 不要使用工会来欺骗类型系统。
  • 不要使用联合存储指针并访问引用。
  • 不要使用联合创建更便宜的类型铸件。

此外,不要使用带有指针的数据的联合,该指针可以从代码中的另一个点删除。您的联合中可能有一个已删除的指针,并且使用另一个定义意外地引用了数据。

最重要的是,如果你不理解这个答案。 不要使用联盟。

答案 1 :(得分:0)

联合可以是获取数据结构的实际二进制表示的一种方法。

#include <iostream>
#include <iomanip>

union MyUnion {
    int integer;
    unsigned char bytes[sizeof(int)];
};

int main() {
    MyUnion foo;
    foo.integer = 42;
    std::cout << "My computer represents " << foo.integer << " as:";
    for (int i = 0; i < sizeof(foo.bytes); ++i) {
      std::cout << ' ' << std::hex << std::setw(2) << std::setfill('0')
                << static_cast<unsigned int>(foo.bytes[i]);
    }
    std::cout << std::endl;
    return 0;
}

在C ++中还有其他方法可以实现这一点,但使用联合会使意图变得相当透明。

请注意,结果可能因平台(little-endian与big-endian)和编译器(如何打包和填充数组和数据类型)而有所不同。大多数时候,你不应该做这样的事情。

有时您必须处理具有多种不同解释的传统二进制格式。 (“如果第一个字节是3,那么下一个值是一个以零结尾的ASCII字符串,最多16个字节,否则,下一个DWORD对齐的int是资源块中的偏移量......”)。如果您理解所涉及的所有字节顺序和包装问题,那么联合使得分离这样的结构变得相对容易。