ブレースの初期化を使用すると、変数にはデフォルト値が割り当てられるという考えに陥りました。しかし、私は間違っていました。
次の例では:
#include <string>
#include <iostream>
#include <stdint.h>
class A
{
public:
A() {}
~A(){}
int var1;
int32_t var2;
int64_t var3;
std::string var4;
double var5;
float var6;
std::string info() const {
return "var1=" + std::to_string(var1) + " " +
"var2=" + std::to_string(var2) + " " +
"var3=" + std::to_string(var3) + " " +
"var4=" + var4 + " " +
"var5=" + std::to_string(var5) + " " +
"var6=" + std::to_string(var6) + " " +
"\n"
;
}
};
int main()
{
A a;
std::cout << "Before assigning variables: " << a.info();
a.var1 = 1;
a.var2 = 2;
a.var3 = 3;
a.var4 = "4";
a.var5 = 5;
a.var6 = 6;
std::cout << "After assigning variables: " << a.info();
a = {};
std::cout << "After brace init assignment: " << a.info();
}
結果は次のとおりです。
Before assigning variables: var1=0 var2=0 var3=4198240 var4= var5=0.000000 var6=0.000000
After assigning variables: var1=1 var2=2 var3=3 var4=4 var5=5.000000 var6=6.000000
After brace init assignment: var1=2114725200 var2=32766 var3=4199416 var4= var5=0.000000 var6=0.000000
それを修正するには:
クラスのメンバー変数が中括弧で初期化されている場合、0またはデフォルト値が割り当てられます。例えば:
class A
{
public:
A() {}
~A(){}
int var1{};
int32_t var2{};
int64_t var3{};
std::string var4{};
double var5{};
float var6{};
};
誰かがこれが起こる理由を説明できますか?ここで何が欠けていますか?
a = {};
は割り当てであり、a
から構築された一時オブジェクトから割り当てられます{}
。暗黙的に生成された割り当ては、すべてのデータメンバーに対してメンバーごとの割り当てを実行し{}
ます。ポイントは、一時オブジェクトがから初期化される方法です。
これはコピーリストの初期化です。効果として、値の初期化が実行されます。
それ以外の場合、braced-init-listが空で、Tがデフォルトのコンストラクターを持つクラス型である場合、値の初期化が実行されます。
値の初期化の効果として、
1)Tがデフォルトコンストラクターのないクラスタイプであるか、ユーザー提供または削除されたデフォルトコンストラクターの場合、オブジェクトはデフォルトで初期化されます。
A
にはユーザー提供のデフォルトコンストラクタがあり、デフォルトの初期化の効果として、そのデフォルトのコンストラクタが一時オブジェクトの初期化に使用されます。ユーザー提供のデフォルトコンストラクタの体が空で、その後、一時的なオブジェクトに対して、var4
しますデフォルト初期化でstd::string
のデフォルトコンストラクタ、ビルドインタイプを持つ他のすべてのデータメンバーは不定値になります。
- デフォルトのコンストラクターを取り除くと、問題は解決します。
(私の強調)
2)Tが、ユーザー提供も削除もされていないデフォルトコンストラクターを持つクラスタイプである場合(つまり、暗黙的に定義された、またはデフォルトのデフォルトコンストラクターを持つクラスである可能性があります)、オブジェクトはゼロで初期化され、その後、default-重要なデフォルトコンストラクターがある場合は初期化されます。
ここでの違いに注意してください。一時オブジェクトは最初はゼロで初期化されます。次に、組み込みタイプのすべてのデータメンバーがに初期化されます0
(var4
まだデフォルトで初期化されています)。
- クラスのメンバー変数が中括弧で初期化されている場合、0またはデフォルト値に割り当てられます。
これは、デフォルトの初期化子リストがどのように機能するかです。
デフォルトのメンバー初期化子を使用します。これは、メンバー宣言に含まれる中括弧または等しい初期化子であり、メンバーがメンバー初期化子リストで省略されている場合に使用されます。
次に、すべてのデータメンバーが指定された初期化子によって初期化されます。あなたのサンプルでは、彼らがすべてだ値に初期化が、効果として、var4
あるデフォルトの初期化、他のメンバーがされ、ゼロに初期化します0
。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加