2011-01-07 11 views
1

const値がオブジェクトのコンストラクタに渡されるとき、それらは参照または値によって渡されるべきですか?
コンストラクタと初期化子のすべての教科書の例は値渡しですが、これは私にとっては非効率的です。定数またはコンストラクタのメンバを参照または値で渡す必要がありますか?

値渡しで引数をすぐに使用してメンバー変数を初期化すると、2つのコピーが作成されますか?これはコンパイラが自動的に処理するものですか?

class Point { 
public: 
    int x; 
    int y; 
    Point(const int _x, const int _y) : x(_x), y(_y) {} 
}; 

int main() { 
    const int a = 1, b = 2; 
    Point p(a,b); 
    Point q(3,5); 

    cout << p.x << "," << p.y << endl; 
    cout << q.x << "," << q.y << endl; 
} 

正しい

class Point { 
public: 
    int x; 
    int y; 
    Point(const int& _x, const int& _y) : x(_x), y(_y) {} 
}; 

どちらもコンパイルして同じことを行うが、対?

+1

「const」を使用すべき/使用すべきではないことについて語っている[GotW記事(#6)](http://www.gotw.ca/gotw/006.htm)があります。 –

答えて

1

ここでは、参照を渡して値を渡すかどうかを選択しています。これらの関数シグネチャは同一であることに注意してください。

Point(int x, int y); 

Point(const int x, const int y); 

ビューの呼び出し元の観点から、パラメータが値で渡されたときにコピーが常に行われるように、パラメータが変更されているかどうかは問題ではありません。

コンストラクタの外にあるその実際のオブジェクトへの参照またはポインタを初期化する場合は参照を渡す必要があります。値が必要な場合は値を渡すのが普通ですが、オブジェクトをコピーするコストが高すぎない限り。 intについては、これは決してありません。

2

値渡しの単純型の場合は、数バイトのデータをコピーするだけです。しかし、ベクトルや文字列のような複雑な型の場合は、const参照を渡す方が良いでしょう。大規模な文字列やベクトルをコピーする必要がない場合は、無駄です。

+0

私はこのコピーは大したことではないことを理解していますが、厳密に言えば、余分なコピーは完全に不要であり、避けるべきですか?このオブジェクトは説明のためのものですが、高性能アプリケーションで数百万を作成しなければならないと言います。そのような些細なコンストラクタの場合、余分なコピーは操作全体の2倍の命令コールを招くかもしれません!もちろん、コンパイラが冗長コピーを削除するほどスマートでない限り。 – Mike

+0

私は、ほとんどのコンパイラがこれを単一のコピーに最適化すると信じています。 – GWW

0

intのような単純なものは、値渡しする必要があります。

大きなオブジェクトがある場合は、不要なコピーを作成しないように参照渡しが意味を持ちます。

オブジェクトが変更可能な場合は、参照またはコピーを渡す間に意味の違いがあります。前者の場合は元の変更が表示され、後者の場合は変更されません。 constへの参照として宣言したとしても、これは当てはまります。

1

intのような小さなプリミティブ型を、参照ではなく値で渡すことをお勧めします。私が正しくリコールすると、隠れたポインタ(つまり、アドレスを渡して自動的に参照解除)としてシーンの裏側に参照が実装されます。つまり、ポインタをコピーして逆参照するオーバーヘッドが発生します(一部のアーキテクチャではintと同じサイズ)。

大きなユーザー定義型では、コピー操作が潜在的に高価になるため、参照渡しを参照することは間違いありません。

+0

値が渡される点はポイントと同じサイズです。 – Mike

関連する問題