はじめに
C++の構造体(struct
)は、全てのメンバ変数がそれぞれ個別のメモリ領域を持ちます。一方、「共用体 (union
)」は、定義された全てのメンバ変数が、一つの同じメモリ領域を共有(共用)するという、特殊な性質を持っています。
これは、複数のデータ型のうち、常にどれか一つしか使わないことが分かっている場合に、メモリを節約するためのテクニックです。共用体のサイズは、その中で最も大きいメンバ変数のサイズになります。
この記事では、union
の基本的な使い方と、その「メモリ共有」という挙動について、サンプルコードで解説します。
union
を使ったサンプルコード
このコードは、ProductCode
(商品コード)という共用体を定義します。この共用体は、id
(数値コード)とshortName
(文字コード)という2つのメンバを持ちますが、どちらか一方しか有効な値として保持できません。
完成コード
#include <iostream>
using namespace std;
// 商品コードを格納する共用体の定義
union ProductCode {
int id; // 数値コード
char shortName[4]; // 3文字の英字コード (+ヌル文字)
};
int main() {
ProductCode code;
// --- 1. 整数メンバ(id)に値を設定 ---
cout << "最初に、数値コードとして 999 を設定します。" << endl;
code.id = 999;
// この時点では両方のメンバが同じメモリを見ている
cout << "数値コード(id): " << code.id << endl;
cout << "文字コード(shortName): " << code.shortName << " (※意味のないデータ)" << endl;
cout << "\n--- 2. 文字メンバ(shortName)に値を設定 ---" << endl;
cout << "次に、文字コードとして 'ABC' を設定します。" << endl;
code.shortName[0] = 'A';
code.shortName[1] = 'B';
code.shortName[2] = 'C';
code.shortName[3] = '\0'; // 終端ヌル文字
// shortNameに書き込んだことで、idの領域も上書きされた
cout << "文字コード(shortName): " << code.shortName << endl;
cout << "数値コード(id): " << code.id << " (※値が破壊された)" << endl;
return 0;
}
コードの解説
union ProductCode { ... };
union
キーワードを使って、ProductCode
という共用体を定義しています。int
型の id
と、char[4]
型の shortName
という2つのメンバを宣言していますが、これらは別々の場所ではなく、同じメモリ領域を異なる解釈で使う、という宣言になります。
メモリの共有
code.id = 999;
:id
メンバに999
を代入すると、共用体のメモリ領域に999
という数値データが書き込まれます。このときshortName
メンバを通じて同じメモリを覗くと、999
のビットパターンを無理やり文字として解釈しようとするため、意味不明なデータが見えます。code.shortName[0] = 'A'; ...
: 次に、shortName
メンバに"ABC"
という文字データを書き込むと、共用体のメモリ領域はA
,B
,C
,\0
というビットパターンで上書きされます。その結果、元々あった999
という数値データは破壊され、id
メンバを通じて同じメモリを覗くと、"ABC\0"
のビットパターンを無理やり数値として解釈した、全く異なる値が見えます。
このように、共用体では、最後に値を書き込んだメンバだけが有効なデータを保持し、それ以外のメンバにアクセスすると、意味のない(破壊された)データを読み込んでしまうことになります。
まとめ
今回は、C++の共用体 union
の基本的な仕組みについて解説しました。
union
は、全てのメンバが同じメモリ領域を共有する。- そのため、同時に一つのメンバしか有効な値を保持できない。
- 複数のデータ型のうち、どれか一つだけを格納する場合のメモリ節約のために使われる。
共用体は、C言語との互換性や、非常に低レベルなメモリ操作など、限定的な場面で使われる特殊な機能です。ほとんどの場合、struct
や、C++17で導入された std::variant
を使う方が、より安全で分かりやすいプログラムになります。