2011-07-22 8 views
13

const &としてパラメータを送信しない理由はありますか?値は変更されず、コピーも行われません。私の理解では、const by valueパラメータはconstがない場合と同じであり(お互いにオーバーロードしないので)、そのままコピーされます。定数参照としての関数パラメータ

大きいオブジェクトがconst &で送信するのが最も良いことはわかっていますが、この行がどこにあるのかわかりません。または、小さいパラメータでもで送信する場合は、は変更またはコピーされません。

注::私はこれを探してみましたが、トピックがかなり曖昧なので、私は良い答えが見つからなかったので、これは既に回答済みですか(お詫び申し上げます)constconst &明らかに大きなものではないオブジェクトに対する値vs const &の利点について)。

+2

あなたは興味深い記事を見つけるかもしれない:http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ – lccarrasco

+0

まさにタイプ私が感謝のために探していたものの!キーワードは非常に一般的なので、検索するのは難しかったです。 –

+0

@ lccarrasco:Dave Abrahamsは、関数内から値でオブジェクトを返すことについて話しています。問題は、関数への入力パラメータです。この場合、OPはconst参照によってネイティブ・タイプ以外のオブジェクトを渡す必要があります。 – Praetorian

答えて

22

読み込み専用の引数をconst参照として渡すことには、一般的に何も問題ありません。それは、確かに最も効率的な方法です。

参照を実際には,というだけでコピーするよりもコストがかかります(コピーが1つのレジスタに収まるなど、コピーによってプリミティブ型を渡すことを検討することをお勧めします)。ポインタなど)。

また、おそらくstd::shared_ptrとイテレータを値渡しすることができます。これはそのためです。

const-valueを渡すのは、の実装です。このようにそれを使用します。

// Declaration: 
int foo(int n, double d); // No "const"! Constness is not part of the interface. 

// Definition 
int foo(int n, const double d) // implementation detail 
{ 
    while (n--) { if (d > n) return n; } 
} 

を実装では、dが好き(あなたが直接、引数変数を使用して(のようなn)にそれらを修正することを選択しない場合があります。または、読み取り専用として扱うことを選択できます)、引数を適切に宣言します。

+2

私はポインタのコピーがプリミティブ型の場合と同じくらい高価であるか悪いと思っていませんでした。 –

+7

参考にしておくと、参照カウントハンドル( 'shared_ptr'など)をスレッド境界を越えて参照渡しすると、参照カウントを安全に減らすことができなくなります** - あなたは*通過する*この場合の値。 – spraff

+0

@spraff:いいです。 –

12

経験則として、あなたは(非const)値によって、このようなポインタ、intboolfloatdoubleなどのプリミティブ型を渡す必要があり、(定数)を参照することにより、このようなstd::stringなどの種類、std::vectorおよびカスタムオブジェクトクラス。このルールの例外として、スマートポインタなど、値渡しのために特別に設計された軽量クラスがあります。

const値で値を渡します。 void foo(const double bar)、意味がありません - なぜfoobarのコピーを変更できないはずですか?パラメータをconstとして宣言すると、ここでは使用されません。

参照によってプリミティブを渡すこともほとんど意味がありません。背後では、パラメータが参照渡しされると、ポインタが値渡しされます。ポインタのコピーは通常プリミティブ型(intなど)をコピーするのと同じくらい高価で、タイプconst int&のパラメータはほとんどのC++プログラマにとっては非常に奇妙です。

+0

できれば私は2つの答えを受け入れるだろう! –

+3

実際に 'const double bar'を好む(私はそれらの中にいません)人がいます。彼らは、関数内のパラメータの値を上書きすることによってバグが発生するのを防ぎます。 –

+0

@larsmansのコメントに追加するだけで、 'const double bar'を使うと' == 'の代わりに' if(bar = 5) 'を誤って実行することを防ぎます。しかし、それはあなたが 'bar'でできることを制限する代償です。あなたのアルゴリズムは何らかの理由で 'bar'のインプレース修正を要求するかもしれません。柔軟性と安全性のトレードオフに過ぎないと思います。あなたが次のプログラマーをどれだけ信頼したいかによって決まります! –

関連する問題