union 是 C/C++ 中「多類型共享同一塊內存」的機制。C++ 擴展允許成員函數、構造函數,但**強烈建議堅持 C 風格慣例**:無構造/析構/拷貝/賦值/虛函數,僅作 POD 類型複用內存。本文系統講解限制原因、正確用法、三大經典模式(重命名、壓縮、類型懲罰)、匿名聯合、判別式模式。
// ✅ 推薦:純數據成員,無構造/析構/虛函數
union DataUnion {
const char* str;
long num;
struct { float x, y, z, w; } vec4;
float arr[4];
};
class Wrapper {
DataUnion data_;
public:
Wrapper(const char* s) { data_.str = s; }
Wrapper(long n) { data_.num = n; }
// 手動管理活躍成員,必要時加判別式 enum { STR, NUM } tag_;
};
struct Vec4 {
union {
struct { float x, y, z, w; };
struct { float r, g, b, a; };
float v[4];
};
};
// 用法:v.x / v.r / v[0] 指向同一 float
struct Compressed {
bool operator==(const Compressed& o) const { return word == o.word; }
union {
struct { char a,b,c,d,e,f,g; };
long long word; // 64 位一次比較 7 個字節
};
};
union FloatInt {
float f;
int i;
};
FloatInt u; u.f = 1.0f;
int bits = u.i; // 0x3F800000 (IEEE 754 表示)
// 用途:快速 float↔int 轉換、提取指數/尾數、自定義哈希
void foo() {
union { int i; float f; }; // 無標籤,直接訪問 i、f
i = 42;
f = 3.14f; // 覆蓋 i
}
// 限制:無成員函數、無私有/保護成員、全局需 static 或置於匿名命名空間
struct TaggedUnion {
enum Type { INT, STR } type;
union {
int i;
char* s;
};
TaggedUnion(int v) : type(INT), i(v) {}
TaggedUnion(const char* v) : type(STR), s(strdup(v)) {}
~TaggedUnion() { if (type==STR) free(s); }
// 訪問器模式
int getInt() const { assert(type==INT); return i; }
};
#pragma pack、固定寬度類型)。std::memcpy、std::bit_cast (C++20)、union 僅在同一編譯單元、低優化、嵌入式場景可控使用。Union 是「內存複用」的鋒利工具。**堅持 C 風格 POD 成員、手動管理活躍狀態、避免跨平台序列化、警惕嚴格別名規則**,即可在嵌入式、遊戲引擎、高性能序列化、網絡協議解析等場景安全發揮威力。現代 C++ 優先考慮 std::variant (C++17) 獲得類型安全的和類型。