web-dev-qa-db-ja.com

コピーコンストラクターがC ++で参照によるパラメーターを受け入れる必要があるのはなぜですか?

コピーコンストラクターにパラメーターを参照で渡す必要があるのはなぜですか?

104
Jony

参照によるものではない場合、値によるものだからです。それを行うにはコピーを作成し、コピーコンストラクタを呼び出します。しかし、それを行うには、新しい値を作成する必要があるため、コピーコンストラクターなどを呼び出します...

(「コピーを作成するには、コピーを作成する必要がある」ため、無限再帰が発生します。)

164
GManNickG

値渡しはコピーコンストラクターを呼び出すため:)

63
Brian Roach

参照渡しの代わりに値渡しがあります。値渡しは実際にはコピー渡しです。コピーを作成するには、コピーコンストラクターが必要です。

コピーコンストラクタを呼び出すためだけにコピーを作成する必要がある場合は、難問になります。

(コンパイラで無限再帰が発生し、実際にそのようなプログラムを取得することはないと思います。)

合理的理由に加えて、§12.8/ 3の標準では禁止されています。

クラスXのコンストラクターの宣言は、その最初のパラメーターがタイプ(オプションでcv修飾)Xであり、他のパラメーターがないか、他のすべてのパラメーターにデフォルト引数がある場合、形式が正しくありません。

19
Potatoswatter

値で渡した場合、無限に再帰的になります

12
Romain Hippeau

組み込みデータ型(ここではcar)以外の引数を取る関数(例:int f(car c))を呼び出すたびに、呼び出し元によって提供された実際のオブジェクトを呼び出された関数のパラメーターの変数にコピーする必要があります。
例:car carobj; f(carobj);

つまり、carobjをcにコピーします。

carobjは、関数fのパラメーターcに対応する必要があります。

コピーを実現するには、コピーコンストラクターが呼び出されます。

この場合、関数fは値渡しを使用して呼び出されます。つまり、関数fは値渡しを行うように宣言されます。

関数fが参照渡しの場合、その宣言はint f(car&c);です。

この場合、car carobj; f(carobj);コピーコンストラクタは必要ありません。

この場合、cはcarobjのエイリアスになります。

上記の2つのシナリオを使用して、わかりやすくするために次のように要約します。1.オブジェクトの値としてパラメーターを取るように宣言された関数の場合、オブジェクトのコピーコンストラクターが呼び出されます。 2.参照渡しとしてパラメーターを受け取るように宣言された関数の場合、パラメーターは呼び出し元が提供するオブジェクトのエイリアスになります。コピーコンストラクターは必要ありません!

問題は、参照渡しが必要な理由です。コピーコンストラクターが参照を受け入れる場合、受信変数は提供されたオブジェクトのエイリアスになります。したがって、呼び出し元が提供したオブジェクトの値をコピーして引数リストのコンストラクターの変数をコピーするために、コピーコンストラクター(この場合、それ自体を呼び出す)は必要ありません。

それ以外の場合、コピーコンストラクターが呼び出し元が提供するオブジェクトを値として取得する場合、つまり値渡しする場合は、指定されたオブジェクトのコピーコンストラクターが必要です。したがって、提供されたオブジェクトを呼び出し元から関数自体(この場合はコピーコンストラクター)に取得するには、コピーコンストラクターを呼び出す必要があります。コピーコンストラクターは、関数パラメーターの初期化中に同じ関数を呼び出すだけです。これが、コンストラクタをコピーするための参照を渡す理由です。

3
Sriraman

値で渡すのではなく、コピーコンストラクターを使用してそのコピーが構築されるため、値ではなく参照としてオブジェクトを渡す必要があります。これは、コピーコンストラクターがそれ自体を呼び出してコピーを作成することを意味します。メモリの。

0
anand tripathi

オブジェクトを参照として渡すことは非常に重要です。オブジェクトが値としてコピーコンストラクターに渡される場合、そのコピーコンストラクターはそれ自体を呼び出して、実際のパラメーターを仮パラメーターにコピーします。したがって、コピーコンストラクターへの呼び出しの無限のチェーンが開始されます。このプロセスは、システムがメモリを使い果たすまで続きます。

したがって、コピーコンストラクターでは、パラメーターを常に参照として渡す必要があります。

0
Dalbir Singh

参照で渡されない場合、値で渡されます。引数が値で渡される場合、そのコピーコンストラクターはそれ自体を呼び出して、実際のパラメーターを仮パラメーターにコピーします。このプロセスは、システムのメモリがなくなるまで続きます。そのため、コピーコンストラクターが呼び出されないように、参照で渡す必要があります。

0
ishaang