コピーコンストラクターの仕組みについて少し混乱しています。私が間違っている場合は修正してください:
メソッドがオブジェクトへの参照をパラメーターとして取り、クラスがコピー コンストラクターを定義する場合、クラスはコンストラクターを使用して自身のコピーを作成し、元のオブジェクトへの参照ではなく関数に渡されますか?
さらに、呼び出すことができます
Object * obj = new Object(&anotherObject);
anotherObject のコピーを作成するには?
コピーコンストラクターの仕組みについて少し混乱しています。私が間違っている場合は修正してください:
メソッドがオブジェクトへの参照をパラメーターとして取り、クラスがコピー コンストラクターを定義する場合、クラスはコンストラクターを使用して自身のコピーを作成し、元のオブジェクトへの参照ではなく関数に渡されますか?
さらに、呼び出すことができます
Object * obj = new Object(&anotherObject);
anotherObject のコピーを作成するには?
いいえ、関数が参照を取る場合:
void f1( Object & o ); // call by reference
その場合、コピーは作成されません。関数が値を取る場合:
void f2( Object o ); // call by value
次に、コピー コンストラクターを使用して、コンパイラーによってコピーが作成されます。
はい、あなたが言うとき:
Object * obj = new Object(anotherObject); // not &anotherObject
コピー コンストラクターが明示的に使用されます (anotherObject が Object 型であると仮定します)。new
ただし、here の使用について魔法は何もありません - この場合:
Object obj2(anotherObject);
コピー コンストラクターも使用されます。
メソッドがオブジェクトへの参照をパラメーターとして受け取る場合、コピー コンストラクターは呼び出されません。その場合、コピー コンストラクター自体を呼び出すと、無限ループが発生します (引数として参照を受け取るため)。
その行は、コピー コンストラクターを呼び出す有効な方法ではありません。ポインターではなく、引数として参照が必要です。
メソッド呼び出しを行っているという事実は、ここでは重要ではありません。関数呼び出し中の参照パラメーターの初期化は、スタンドアロンの参照初期化と変わらず、同じ規則によって管理されます。
参照の初期化のルールは少し複雑ですが、要点は、初期化子が左辺値 (この場合のメソッド呼び出しの引数) であり、参照の型が初期化子の型と同じである場合 (つまり、パラメータの型が引数の型と同じである場合)、参照は直接バインドされます。つまり、コピーは作成されません。
Object a; // class type
Object &r = a; // no copying
const Object &cr = a; // no copying
これらの要件が満たされない場合 (たとえば、初期化子が右辺値である場合など)、すべて依存します。場合によっては、コピーが実行される可能性があります。例えば
const Object &tr = Object();
コンパイラによって次のように解釈できます。
const Object &tr = Object(Object(Object(Object())));
実装に依存する有限数のコピーを使用します。もちろん、効率上の理由から、コンパイラは通常、コピーが許可されている場合でも、不要なコピーを作成しないようにしています。
コンパイラのコピー動作の有効性についてしばしば議論を巻き起こす古典的な例は、次のような式での参照の初期化です。
Object a;
const Object &r = <some condition> ? a : Object();
C++ 参照セマンティクスに精通している人は、上記のような式が、参照の初期化中に余分なコピーを実行するための標準的な許可の背後にある理論的根拠である可能性が高いことを理解するでしょう。
コピー コンストラクターは、参照渡しではなく、値渡しの場合にのみ呼び出されます。参照によるコピーは必要ありません (これは参照の目的の一部です!) したがって、コピー コンストラクターは呼び出されません。
どちらの場合もいいえ。最初のケースでは、そのオブジェクト自体への参照が渡され、コピーは作成されません。2 番目のケースでは、コンストラクターにポインターを渡しているobject
ため、コピーは作成されません。したがって、オブジェクトには、次のようなコンストラクター (コピー コンストラクターではない) が必要です。object(anotherClass*)