このような関数があるとします
bool verifyObject(const myObj& obj);
またはこれ
bool verifyObject(const myObj obj);
私が理解している限りでは、2 番目のケースのようなものを渡すと、コピーが作成されます。ただし、コンパイラは constness を利用して、最初のケースのように渡すことができます。そのため、どちらの方法でも const オブジェクトを渡すことに違いはありません。
私が間違っている?
呼び出し元の観点から見た 2 番目のものは、
bool verifyObject(myObj obj);
さらに、宣言として、これら 2 つは完全に同等です。
bool verifyObject(myObj obj);
bool verifyObject(const myObj obj);
関数宣言では、最上位の const はすべて無視されます。違いは定義中にのみ現れます
bool verifyObject(const myObj obj)
{
obj.NonConstMethod(); //compiler error!
}
呼び出し元がまったく気にしない関数内のコピーを変更することはできません。関数の実装者として、あなた自身の目的のためだけです。
私が理解している限りでは、2 番目のケースのようなものを渡すと、コピーが作成されます。
はい; ただし、場合によっては (一時的なものを渡す場合など)、コピーが省略される可能性があります。
ただし、コンパイラは constness を利用して、最初のケースのように渡すことができます。
いいえ; 引数が一時的なものでない限り、これはコピーを省略できる状況の 1 つではありません。関数を呼び出すとき、関数を宣言するときにこのようなconst
トップレベルを省略できるため、コンパイラはパラメーターが関数内にあることさえ知らない場合があります。const
したがって、参照を渡すことがコピーを渡すことと同等であると判断できたとしても (コピー コンストラクターまたはデストラクタに観察可能な副作用がある場合、またはクラスに変更可能なメンバーがある場合はそうではありません)、それはできません。呼び出し元はその変更を知る方法がないため、呼び出し規約を変更してください。
そうは言っても、関数がインラインである場合、またはコンパイラがプログラム全体の最適化を行う場合、このような最適化は可能です。ただし、プログラムの動作を変更しない場合に限ります。
2 番目の例 (値渡し) では、コンパイラがオブジェクトのコピー コンストラクターを呼び出してそのコピーを渡すため、const 修飾子はほとんど違いがありません。一方、const 参照による受け渡し (const myObj& obj) は、オブジェクトへの参照のみを渡します (コピーは作成しません)。その場合、呼び出された関数は、obj を介してオブジェクトの状態を変更できません。