3

このような関数があるとします

bool verifyObject(const myObj& obj);

またはこれ

bool verifyObject(const myObj obj);

私が理解している限りでは、2 番目のケースのようなものを渡すと、コピーが作成されます。ただし、コンパイラは constness を利用して、最初のケースのように渡すことができます。そのため、どちらの方法でも const オブジェクトを渡すことに違いはありません。

私が間違っている?

4

3 に答える 3

3

呼び出し元の観点から見た 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!
}

呼び出し元がまったく気にしない関数内のコピーを変更することはできません。関数の実装者として、あなた自身の目的のためだけです。

于 2013-05-14T14:08:35.000 に答える
2

私が理解している限りでは、2 番目のケースのようなものを渡すと、コピーが作成されます。

はい; ただし、場合によっては (一時的なものを渡す場合など)、コピーが省略される可能性があります。

ただし、コンパイラは constness を利用して、最初のケースのように渡すことができます。

いいえ; 引数が一時的なものでない限り、これはコピーを省略できる状況の 1 つではありません。関数を呼び出すとき、関数を宣言するときにこのようなconstトップレベルを省略できるため、コンパイラはパラメーターが関数内にあることさえ知らない場合があります。constしたがって、参照を渡すことがコピーを渡すことと同等であると判断できたとしても (コピー コンストラクターまたはデストラクタに観察可能な副作用がある場合、またはクラスに変更可能なメンバーがある場合はそうではありません)、それはできません。呼び出し元はその変更を知る方法がないため、呼び出し規約を変更してください。

そうは言っても、関数がインラインである場合、またはコンパイラがプログラム全体の最適化を行う場合、このような最適化は可能です。ただし、プログラムの動作を変更しない場合に限ります。

于 2013-05-14T14:21:26.720 に答える
1

2 番目の例 (値渡し) では、コンパイラがオブジェクトのコピー コンストラクターを呼び出してそのコピーを渡すため、const 修飾子はほとんど違いがありません。一方、const 参照による受け渡し (const myObj& obj) は、オブジェクトへの参照のみを渡します (コピーは作成しません)。その場合、呼び出された関数は、obj を介してオブジェクトの状態を変更できません。

于 2013-05-14T14:14:25.007 に答える