2012-04-21 12 views
3

すべての関数がパラメータで行う必要がある場合は、その値を参照してください。パラメータを渡すエチケット(C++)const&vs値

私の同僚は、小さなタイプでは問題ではないと述べましたが、私は同意しません。このオーバー

void function(char const& ch){ //<- const ref 
    if (ch == 'a'){ 
     DoSomething(ch); 
    } 
    return; 
} 

#include <iostream> 
#include <cstdlib> 

int main(){ 

    char ch; 
    char& chref = ch; 

    std::cout << sizeof(ch) << std::endl; //1 
    std::cout << sizeof(chref) << std::endl; //1 

    return EXIT_SUCCESS; 
} 

しかし、私は実行します。

void function(char ch){ //<- value 
    if (ch == 'a'){ 
     DoSomething(ch); 
    } 
    return; 
} 

は、彼らが私に同じ大きさに見える

だから、これを行うにはどんな利点がありますこれが常に正しいかどうかは分かりません。
追加のオーバーヘッドが発生せず、それ自体が文書化されているので、私は正しいと思います。
しかし、私の推論と仮定が正しいかどうかコミュニティに尋ねたいと思いますか?

+1

あなたのデモコードは、 'sizeof(ch)'が 'sizeof(ch)'と同じであることを示しているようです。 –

+1

これらのうちのどれかのために 'sizeof(chref)'を指定したとしても、同じサイズになります。しかし、これは無関係です。なぜなら、 'sizeof(chref)'を実行すると、実際にはchのサイズを伝えているからです。参照を初期化すると、参照が実際に行われたかのようにすべての操作が動作します。しかし、それは舞台裏で起こっているかもしれないコンパイラの魔法について何も教えてくれません。 –

+0

@JonathanLeffler固定 –

答えて

2

sizeof(chref)sizeof(ch)と同じであっても、参照することによって文字を渡すと、ほとんどのシステムでより多くのバイトを取るん:標準の参照の実装について具体的な何かを言うことはありませんが、アドレス(すなわちポインタ)が定期的に渡されます舞台裏で最適化をオンにすると、おそらく問題ではありません。テンプレート関数を記述するとき、変更されない未知の型の項目は常にconst参照によって渡されます。

限り小さなタイプが行く、あなたはあなたの関数のシグネチャによって引数をタッチするつもりはない点を強調するためにconst修飾子で値によってそれらを渡すことができます。

void function(const char ch){ //<- value 
    if (ch == 'a'){ 
     DoSomething(ch); 
    } 
    return; 
} 
1

サイズはではなく、と同じです。結果はABI呼び出し規約に依存しますが、sizeof(referenceVariable)sizeof(value)を生成します。

パラメータですべての関数を処理する必要がある場合は、その値を参照してください。常に定数参照によってそのパラメータを渡すべきではありませんか?私は何

。私は人々が私に同意していないことを知っており、価値のある小さな組み込み品を渡すことを主張するか、constを省略することを好む。参照渡しは、命令を追加したり、より多くの領域を消費することができます。私はこの方法での一貫性を渡します。また、常に特定のプラットフォームに合格する最良の方法を測定することは、維持するのが面倒です。

可読性を超える利点はありません(ご希望の場合)。パフォーマンスはと非常にわずかにになる可能性がありますが、ほとんどの場合考慮されません。

これらの小さな組み込み関数を値で渡す方が一般的です。値渡しの場合は、const(宣言とは関係なく)定義を修飾することができます。

私がお勧めするのは、大部分のチームは単にそれをパスしてそれに固執する方法を選択するだけで、すべての命令がの場合は以外のパフォーマンスに影響しないはずです。 constは決して傷つきません。

+1

はい。あなたのプログラムが十分に速くない、そして(b)「十分に速くない」と「十分に速い」との差が参照渡しであるという、非常に起こりにくい*イベントでは、それを再訪することができます。それが起こるまで、あなたの意図する意味を伝えるものは何でもベストなのです。 – Ben

+0

@Ben絶対に+1。私は過去にいくつかのアーキテクチャーでそれを測定しており、アセンブリーに落としたくない高度に最適化されたパフォーマンス重視のプログラムでは、その違いは重要ではないと結論付けました。 – justin

0

私の意見では、const参照渡しの一般的なアプローチは良い習慣です(ただし、あなたの例のいくつかの注意点については下記を参照してください)。一方、あなたの友人は、組み込み型の場合、参照渡しで大きなパフォーマンスが得られてはならず、わずかなパフォーマンスの低下につながる可能性があることは間違いありません。私はCのバックグラウンドから来ているので、私はポインタの観点から(たとえ微妙な違いがあっても)考えてみる傾向があり、 "char *"は私が使っているプラ​​ットフォームの "char"よりも大きくなりますおなじみの

[EDIT:削除間違った情報]

一番下の行は、私の意見では、あなたがより大きなユーザー定義型を渡す、としているときに、呼び出される関数にのみ、それらを変更せずに値を読み取るする必要があるということです、 "type const &"を渡すことは良い方法です。あなたが言うように、それは自己文書化であり、内部APIのさまざまな部分の役割を明確にするのに役立ちます。

+1

'const char const&'のようなものはありません。 'const'は最初の単語でない限り、その値をその左にバインドします。その場合、その単語はその値にバインドされます。だから、あなたが言ったのは 'char const const&'です。'char const&'は 'char const * const'とほぼ同じです。つまり' const T& '/' T const& '(同じもの)は値を変更できません。 –

+0

あなたは正しいです。これをC++で処理しなければならないので、数年経っています。 IIRCはこれをコンパイルするかもしれませんが、実際には余計です。説明をありがとう。 C言語のポインタを使った最近の私の仕事は私を捨てたと思います。 – coydog

+2

@coydog:それが間違っている場合は、情報を削除するためにあなたの投稿を編集する必要があります。 –

2

小さい値の場合、参照を作成して逆参照するコストは、コピーするコストよりも大きくなる可能性があります(違いがある場合)。これは、参照パラメータがほとんど常にポインタとして実装されていると考える場合に特に当てはまります。 constという値を宣言しただけでは、両方の文書が同じように良好になります(この値を入力に使用していて、変更されません)。私は一般的に、すべての標準ビルトインタイプをconst値で、すべてのユーザ定義/ STLタイプをconst &とします。

chrefchのエイリアスにすぎないため、sizeofの例に欠陥があります。どんな種類のTでも、同じ結果がsizeof(T)になります。

3

あなたの同僚は正しいです。小さな型(char、int)の場合、変数が変更されない場合、参照渡しは意味がありません。値渡しは、ポインタのサイズ(参照渡しの場合に使用される)のサイズが小さな型のサイズ程度であるため、より良いでしょう。

さらに、値渡しは、より少ない型付けであり、わずかに読みやすくなります。