メンバーを0に初期化するカスタムコンストラクターを作成する構造があります。古いコンパイラでは、リリースモードでは、memsetを0にしないと、値が初期化されないことがわかりました。
私は今、この構造体を共用体で使用したいのですが、非自明なコンストラクターがあるためエラーが発生します。
したがって、質問1。デフォルトのコンパイラー実装コンストラクターは、構造体のすべてのメンバーがヌルで初期化されることを保証しますか?非自明なコンストラクターは、すべてのメンバーのmemsetを「0」にして、クリーンな構造を確保します。
質問2:コンストラクターを基本構造に指定する必要がある場合、その要素を含むようにユニオンを実装して、初期化された基本要素を0にするにはどうすればよいですか?
質問1:デフォルトのコンストラクターは、C++標準に従ってPODメンバーを0に初期化します。以下の引用テキストを参照してください。
質問2:コンストラクターを基本クラスで指定する必要がある場合、そのクラスを共用体の一部にすることはできません。
最後に、ユニオンのコンストラクターを提供できます。
union U
{
A a;
B b;
U() { memset( this, 0, sizeof( U ) ); }
};
Q1の場合:
C++ 03、12.1コンストラクターから、ページ190
暗黙的に定義されたデフォルトコンストラクターは、空のmem-initializer-list(12.6.2)と空の関数本体を使用して、そのクラスのユーザー作成のデフォルトコンストラクターによって実行されるクラスの初期化セットを実行します。
C++ 03から、8.5初期化子、ページ145
タイプTのオブジェクトをデフォルトで初期化するには、次のことを意味します。
タイプTのオブジェクトをゼロで初期化するとは、次のことを意味します。
Q2の場合:
C++ 03、12.1コンストラクターから、ページ190
コンストラクターは、暗黙的に宣言されたデフォルトコンストラクターであり、次の場合に簡単です。
C++ 03、9.5ユニオン、pg 162から
ユニオンにはメンバー関数(コンストラクターおよびデストラクターを含む)を含めることができますが、仮想(10.3)関数は含めることができません。ユニオンには基本クラスがありません。ユニオンは基本クラスとして使用されません。非自明なコンストラクター(12.1)、非自明なコピーコンストラクター(12.8)、非自明なデストラクター(12.4)、または非自明なクラスのオブジェクトコピー代入演算子(13.5.3、12.8)は、ユニオンのメンバーにすることも、そのようなオブジェクトの配列にすることもできません
C++ 11で改善された点
Stroustrupによって記述された 彼自身として、これを合法的に行うことができます( WikipediaのC++ 11に関する記事 からそのリンクに到達しました)。
ウィキペディアの例は次のとおりです。
#include <new> // Required for placement 'new'.
struct Point {
Point() {}
Point(int x, int y): x_(x), y_(y) {}
int x_, y_;
};
union U {
int z;
double w;
Point p; // Illegal in C++03; legal in C++11.
U() {new(&p) Point();} // Due to the Point member, a constructor
// definition is now *required*.
};
Stroustrupはもう少し詳しく説明します。
AFAIKユニオンメンバーには、コンストラクターまたはデストラクターがない場合があります。
質問1:いいえ、そのような保証はありません。コンストラクターの初期化リストにないPODメンバーはデフォルトで初期化されますが、これはユーザーが定義したコンストラクターであり、初期化リストがあります。コンストラクターを定義しない場合、または初期化子リストと空のボディなしでコンストラクターを定義した場合、PODメンバーは初期化されません。
非PODメンバーは常にデフォルトのコンストラクターを介して構築されます。デフォルトのコンストラクターは、合成された場合、再びPODメンバーを初期化しません。ユニオンメンバにコンストラクタがない場合、ユニオン内の構造体のPODメンバが初期化されないことがほぼ保証されます。
質問2:構造/ユニオンはいつでも初期化できます:
struct foo
{
int a;
int b;
};
union bar
{
int a;
foo f;
};
bar b = { 0 };
nwesen の投稿に対するGreg Rogersのコメントで述べたように、ユニオンにコンストラクタ(および必要に応じてデストラクタ)を与えることができます。
struct foo
{
int a;
int b;
};
union bar
{
bar() { memset(this, 0, sizeof(*this)); }
int a;
foo f;
};
このようなことはできますか?
class Outer
{
public:
Outer()
{
memset(&inner_, 0, sizeof(inner_));
}
private:
union Inner
{
int qty_;
double price_;
} inner_;
};
...またはこのようなものですか?
union MyUnion
{
int qty_;
double price_;
};
void someFunction()
{
MyUnion u = {0};
}