2011-12-22 15 views
7

は例を考えます。C++で関数名の前にアンパサンドを使用するとどういう意味ですか? m_Labelはプライベートクラスのメンバ変数である</p> <pre><code>inline string &GetLabel() { return m_Label; }; </code></pre> <p>:

私はそれを理解していると思いますが、この関数は変数m_Labelへの参照を返します。私のプログラム全体でこれを使うことの意義は何でしょうか?参照の代わりに値を返す方が良いでしょうか?ありがとうございました!

答えて

6

プライベートメンバーへの参照を返します。

これが望ましい多くのケースがありますが、いくつか注意する必要があります。

IMO全体的なパフォーマンスの理由から、整数型ではない内部オブジェクトのコピーを返すことは、一般的にはお勧めできません。はい、私は時期尚早な最適化は良くありませんが、これは実際には最適化ではないことです。呼び出し側がパフォーマンスの影響を判断できるようにするのは良いパフォーマンスの方法です。コピーが必要な場合は、それを参照として割り当てる変数を宣言することはできません。

私はここで使う親指の2つの一般的なルールがあります。

1)あなたは、呼び出し元がconst参照として戻り値を宣言し、直接プライベートオブジェクトを変更することができるようにしたくない場合は、次の

inline const string& GetLabel() const{ return m_Label; } 

2)呼び出し側は、クラスメソッドから返された参照を決して格納しないでください。親オブジェクトがスコープ内にあることが保証されている場合にのみ、ローカルで使用する必要があります。

何らかの理由で内部オブジェクトへの参照を格納するために呼び出し元が必要な場合は、代わりにスマートポインタを使用します。

11

戻り値の型と同じくらい、アンパサンドは関数名の前にはありません。 stringへの参照が返されます。

これは、この関数の呼び出し元が参照によってm_labelの値を変更できることを示しています。一方、文字列をコピーすることはありません。両方の世界のベスト

inline const string& GetLabel() const 
{ 
    return m_Label; 
} 

:あなたはそうのように、constとなる基準や機能をお勧めします。あなたはコピーを避けますが、発信者はあなたのオブジェクトを変更することはできません。

+0

実際、あなたはおそらくconstと非constバージョンの両方を望んでいます。 – ildjarn

+0

@ildjamそれは部分的にしか真実ではありません。呼び出し元がオブジェクトを直接変更できるようにする必要がある場合を除き、通常はconstバージョンを提供するだけです。非constバージョンを提供する場合は、constバージョンを提供する必要があります。これにより、親オブジェクトへのconst参照がある場合でも読み取り専用アクセスを得ることができます。 – Gerald

+1

@Gerald:申し訳ありませんが、私は明確にする必要があります - あなたがリファレンスを返す非constバージョンを望むなら、あなたはほぼ確実にconstバージョンも望んでいました。 – ildjarn

1

あなたは正しいです。これは文字列メンバへの参照です。

呼び出し元が値を割り当てたり、返された文字列を変更したりすると、メンバー変数も変更されることになります。これが目的でない場合は、カプセル化を破らないように値でコピーを返すことができます。

2

参照を返すと、呼び出したコードは、返された後にメンバー変数の値を変更できることを意味します。それが起こることを意図しない限り、それは非常に危険です。

constの方がいいですか、価値によって返されます(&を除く)。

2

一つの含意は、囲んでいるオブジェクトが破壊された場合、参照が無効になることである。

Object* o = new Object; 
string& label = o->GetLabel(); 
delete o; 
// label becomes a dangling reference here. 

別の含意は、発信者が文字列を変更できることです。 const参照を返すことでそれを修正できます。

関連する問題