私の使用class、structおよびunionは次のとおりです。
class振る舞いのあるオブジェクトの場合。
structパッシブデータ用。
union異なるデータに異なるタイプとしてアクセスする必要がある非常に特殊なケースの場合。
私はずっと前にGoogleC++スタイルガイドunionでこれを読んでいて(要点を除いて)、それ以来それをフォローしていました。
sを使用structしてパッシブデータ(オブジェクトに動作がアタッチされていないオブジェクト)を伝送することには、メンバーのデフォルトの公開という利点があるため、ゲッターやセッターなしでアクセスできます。一部のメンバーデータを割り当てる前にチェック/変更する必要がある場合、または一部のメンバーデータを取得する前に計算/変更する必要がある場合、IMHOはSetter / Getterペアが必要であり、オブジェクトはのclass代わりになりstructます。
タイプについては、メンバーへの奇妙なアクセスを必要とする、または一部のコンテキストで一部のメンバーを別のタイプとして扱う必要がある、unionある種のデータ構造に役立つと思います。たとえば、3DベクトルまたはIPアドレス:
union 3DVector
{
double x, y, z;
double vector[3];
} v;
// Acess members with name
v.x = 6.0; v.y = 7.0; v.z = 8.0;
// Acess members as a vector
Normalize(v.vector);
union IPAddress
{
int binary;
char octet[4];
} ip;
// Acess the binary address
std::cout << std::hex << ip.binary << '\n';
// Print in a human-readable form
std::cout << static_cast<int>(ip.octet[0]) << '.'
<< static_cast<int>(ip.octet[1]) << '.'
<< static_cast<int>(ip.octet[2]) << '.'
<< static_cast<int>(ip.octet[3]) << '\n';
上記の機能は、オーバーロード演算子と変換演算子で実現できますが、このunionアプローチは私にはわかりやすいように見えます。
unionsはテンプレート化することもでき、コンストラクタ/デストラクタを持つことができます。これは、シリアル化の目的で役立つ可能性があります(すべての種類のオブジェクトではありません)。
template <typename T> union Serializer
{
Serializer(const T &o) : object(o) {}
T object;
char binary[sizeof(T)];
};
SomePODObject obj; // Only POD objects please!
Serializer s(obj);
SendBuffer(s.binary);