const ClassA& curShot = vec_shots[curShotIndx];
上記のコードでは、curShotオブジェクトが作成され、同じステップで割り当てられます。私の質問は、上記のステートメントでどのコンストラクターが使用されているかです。デフォルトのコンストラクターの後に代入演算子が続くと思いましたが、代わりにコピーコンストラクターを呼び出しているようです。なぜそうなのですか?
const ClassA& curShot = vec_shots[curShotIndx];
上記のコードでは、curShotオブジェクトが作成され、同じステップで割り当てられます。私の質問は、上記のステートメントでどのコンストラクターが使用されているかです。デフォルトのコンストラクターの後に代入演算子が続くと思いましたが、代わりにコピーコンストラクターを呼び出しているようです。なぜそうなのですか?
何が起こるかというと
vec_shots[curShotIndx];
に割り当てる参照を返しますconst ClassA& curShot
。このステップには、オブジェクトの作成は含まれていません。したがって、コンストラクターは呼び出されません (デフォルト コンストラクターでもコピー コンストラクターでもありません)。
あるオブジェクト インスタンスを別のオブジェクト インスタンスに割り当てるのではなく、参照のみを割り当てるため、代入演算子も呼び出されません。このコードでは、複数の (既存の) オブジェクト インスタンスを処理していません。したがって、構築や代入は呼び出されません。
コンストラクターは使用されcurShot
ず、それ自体はスタンドアロン オブジェクトではなく、既存のオブジェクトへの参照またはエイリアスです。
また、初期化と代入を同じステップで行うことはできません。たとえば、あなたが持っていたとしましょう
ClassA original;
ClassA copy = original;
ここでcopy
は、 は割り当てられておらずoriginal
、 を使用して初期化されていoriginal
ます。これをコピーの初期化と呼びます。
あなたがした場合
ClassA copy2(original);
これは直接初期化と呼ばれます。
コピー コンストラクターは両方のインスタンスで呼び出されます。(コピー省略が発生する可能性があるため、呼び出されない可能性がありますが、使用可能である必要があります)
割り当ては、operator =
既存のオブジェクトで使用する場合です。
ClassA x;
ClassA y;
x = y; //assignment
「コピーコンストラクターを呼び出すようです」と書いたので、質問のアンパサンドはタイプミスだと思います。
その場合、あなたがそうするなら
const ClassA curShot = vec_shots[curShotIndx];
コピー構築として評価されます。醜いのと同じconst ClassA curShot( vec_shots[curShotIndx] )
です。
ただし、書くと
ClassA curShot; // I skipped the "const", because otherwise the example would be invalid.
curShot = vec_shots[curShotIndx];
次に、デフォルトのコンストラクターがopearator=
呼び出され、2 行目で an が呼び出されます。
さらに、「=」は NEITHER コピーコンストラクター NOR を呼び出すことを意味する可能性が非常に高いため、次のようにoperator=
することができます。
const ClassA f(){ return ClassA(); }
//...
const ClassA curShot = f(); // we would expect here a copy constructor call
ここで -- コンパイラが戻り値の最適化を使用し、通常はそうしている場合 -- curShot に対して呼び出されるのはデフォルトのコンストラクタのみです。
このステートメントは、curShot を参照として定義しているだけで、新しいオブジェクトではありません。