機能があります
void h(A const a){...};
私がそれを作った場合、振る舞いが変わる可能性はありますか?
void h(A const &a){..same body as above..};
タイプAは自由に定義できます。もちろん。
最初のオーバーロードでは、h は 'a' を変更できません。これは、すべての目的で、'h' の本体にある const です。ただし、これには、初期化 'a' をコピーするためのコピー コンストラクターが含まれます。
したがって、最初のケースでは、'A' にアクセス可能なコピー コンストラクターが必要です。同様に、A でアクセス可能なデストラクタが必要です。
2 番目のケースでは、コピーの初期化は必要ないため、'A' のアクセス可能なコピー コンストラクタ/デストラクタは必要ありません。
また、最初のケースでは、「A」の派生オブジェクトが引数として渡された場合、「a」は「スライス」されます。2 番目の関数には、基本クラスの参照が派生オブジェクトにバインドできるため、「スライス」の問題はありません。したがって、この場合、アクセス可能なデストラクタも必要ありません。
C++11 では、最初の関数では、'h' の呼び出し方法に応じて、アクセス可能な 'copy' または 'move' コンストラクターを持つ 'A' が必要になります。
type のコピー コンストラクターで何が起こるかに応じてA
、はい、異なる動作が発生する可能性があります。
他の回答で述べたように、参照ではなく値で渡すとA
、コードの別のパスであるコピー コンストラクターが実行されます。クラスが何らかのリソースを処理する場合、クラスA
をコピーすると、そのリソースの別のインスタンスが関数に渡される可能性があります。
A
事実上、それはすべて、実際にどのクラスが行うかに依存します。
a
最初のケースで派生したクラスが渡された場合のコピー構築のコストと潜在的なスライスの問題について他の人がここに書いたことに加えてA
、これらの関数には異なるシグネチャがあります。
が何らかのクラスのメンバー関数であり、基本クラスの
関数h
を上書きしようとすると、2 つの形式は署名が異なるため、異なる関数と見なされます。つまり、最初のフォームは 2 番目のフォームをオーバーロードできません。virtual
h
h
次に、基本クラスへのポインターを介して派生クラスを呼び出し、派生クラスから呼び出したいh
場合、それらのシグネチャは同一である必要があります。それ以外の場合はh
、基本クラスの が呼び出されます。これにより、目に見える違いが生じる可能性があります。
簡単な答え: いいえ。
より長い答え: 最初の例では、の完全なコピーがa
スタックに作成されます。関数の呼び出しに関係なく、渡したパラメーターに対して A のコピー コンストラクターが呼び出されます。関数が終了すると、のデストラクタa
が呼び出されます。実装によっては、A
非常に高価になる可能性があります。
さらに、最初の関数は、コピー コンストラクターにアクセスできないオブジェクト、抽象クラス (A
が抽象の場合)に対して呼び出すことはできませんA
。
2 番目の関数には、これらの制限はありません。
TL;DR: 最初のバージョンは絶対に使用しないでください (ただし、マイレージは異なる場合があります)。