考慮事項は次のとおりです。
1) コピーを返却しますstring
。次に、ドキュメントは単純であり(「...の現在の値を返す」)、関数は遅いです(戻り値が...理論的には、コンパイラがstring
副作用のないコピーを持つ値型として認識し、呼び出し元がコピーを使用している間は参照先が変更できないことを証明し、代わりに参照を使用することは可能です。しかし、それだけで十分でしょうか?)。
2) 参照を返しますconst string&
。次に、ドキュメントは複雑です(「現在の値を含むオブジェクトへの参照を返しますstring
...この参照は、次の時間まで有効です...その時間の次のサブセットに対して同じ値を含み続けます... 」)。呼び出し元がコピーを必要としない場合、関数は高速です。string
クラスの実装は、適切なライフタイムで返すものが何もないため、将来的に常にその文字列をデータメンバーとして格納するようにかなり制限されています。
エイリアシングは潜在的に高速ですが (コピーを回避する場合)、複雑です (参照元が変更または消失する可能性があるため)。そのため、参照を返す関数は潜在的に高速ですが複雑です。なお、(1)は「オブジェクトのプロパティを返すゲッター」ですが、(2)は「オブジェクトのprivateメンバーを返すゲッター」です。したがって、ゲッターが悪である場合、(2) は(1)よりも悪です。
他の密結合クラスがデータを取得するためのハックとしてゲッターが本質的に存在する場合、またはクラスがいつ変更されるかについて非常に明白なセマンティクスを持っている場合、たとえば「オブジェクト」、または文字列が非常に巨大であると予想される場合は、コピーを取得することはめったになく、呼び出し元は値の動作ではなくビューの動作を期待するため、参照によって公開することが合理的です. 私が書いているクラスが明示的に「大きな文字列を保持し、X を実行する一方で、X を実行するもの」として明示的に設計されていない限り、安全のために、インターフェイスが永久に互換性があると想定されている場合は、おそらく値を返します。文字列が見えます」。
不変のガベージコレクションされた文字列は、この問題を解消します。これはおそらく、高水準言語の設計者にとって魅力的な理由の 1 つです。