私の使用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
アプローチは私にはわかりやすいように見えます。
union
sはテンプレート化することもでき、コンストラクタ/デストラクタを持つことができます。これは、シリアル化の目的で役立つ可能性があります(すべての種類のオブジェクトではありません)。
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);