- 共用体が CopyConstructable および Assignable である場合、std::vector の要件を満たしています。
- はい:
MyUnion* ptr = new MyUnion();
- ポインターのコンテナーは状況によっては機能しますが、ポインターを所有するコンテナーが必要な場合は、Boost のptr_* コンテナーを参照してください。ただし、ここでは、非ポインターのコンテナーまたは所有していないポインターのコンテナーのいずれかを使用しているように見えますが、どちらも問題なく、ベクターでは一般的です。
デフォルトでは、すべての型は CopyConstructable と Assignable の両方です。(「コピー可能」は、これらの概念の結合を意味するために使用されますが、標準では個別に指定されています。) これは、特定の状況を除いて、コピー ctor と op= がクラスに追加されるためです (結合は 1 つのクラス型です)。オンラインで参考文献がいくつかありますが、オンラインで自由に入手できるもので、これらを詳しく説明しているものを 1 つも知りません。
次のように、それを防ぐために最善を尽くす必要があります。
- コピー ctor または op= 非公開にする
- コピー ctor または op= が非 const 参照を取るようにする
- クラス型に非 CopyConstructable または非代入可能メンバーを与える
例:
union CopyableUnion {
int n;
char c;
double d;
};
union NonCopyableUnion {
int n;
char c;
double d;
NonCopyableUnion() {} // required, because any user-defined ctor,
// such as the private copy ctor below, prevents the supplied
// default ctor
private:
NonCopyableUnion(NonCopyableUnion const&);
NonCopyableUnion& operator=(NonCopyableUnion const&);
};
int main() {
CopyableUnion a;
CopyableUnion b = a; // fine, uses copy ctor
b = a; // fine, uses op=
NonCopyableUnion c;
NonCopyableUnion d = c; // compile error (copy ctor)
d = c; // compile error (op=)
return 0;
}
注:そして、何かがコピー可能だからといって、それがあなたが望むことを意味するわけではありません! 例:
struct A {
int* p;
A() : p(new int()) {}
// the provided copy ctor does this:
//A(A const& other) : p(other.p) {}
// which is known as "member-wise" copying
~A() { delete p; }
};
int main() {
A a;
{
A b = a;
assert(b.p == a.p); // this is a problem!
} // because when 'b' is destroyed, it deletes the same pointer
// as 'a' holds
return 0; // and now you have Undefined Behavior when
// ~A tries to delete it again
}
もちろん、同じことが労働組合にも当てはまります。ただし、修正は同様に適用されます。
struct A {
int* p;
A() : p(new int()) {}
A(A const& other) : p(new int(*other.p)) {}
~A() { delete p; }
};
(もしあなたがそれを見つけたなら、そうです、あなたが op= を使おうとすると、 A はもともと copy ctor で持っていたのと同じように問題を抱えています。)