引数が渡されるC++関数を作成するとき、オブジェクトが変更されないことを保証できる場合は常にconstを使用する必要があります。ポインターが変更されない場合はconstポインターを使用する必要があります。
他にこのプラクティスが助言されるのはいつですか?
いつconst参照を使用しますか?たとえば、ポインターを介して渡すだけの場合の利点は何ですか?
これについてはどうですかvoid MyObject::Somefunc(const std::string& mystring)
文字列が実際にすでに不変オブジェクトである場合、const文字列を持つことのポイントは何でしょうか?
Constを追加するかどうかを尋ねるのは間違った質問です残念です。
_void modifies(T ¶m);
void modifies(T *param);
_
このケースは主にスタイルに関するものです。呼び出しをcall(obj)
またはcall(&obj)
のようにしたいですか?ただし、違いが重要な点が2つあります。 nullを渡せるようにするには、ポインタを使用する必要があります。また、演算子をオーバーロードしている場合は、代わりにポインターを使用できません。
_void doesnt_modify(T const ¶m);
void doesnt_modify(T param);
_
これは興味深いケースです。経験則では、「安価なコピー」タイプは値で渡されます。これらは一般に小さいタイプですが(常にではない)、他のタイプはconst refで渡されます。ただし、関数内でコピーを作成する必要がある場合は、 値で渡す必要があります です。 (はい、これは実装の詳細を公開します。C'est le C++。)
_void optional(T const *param=0);
// vs
void optional();
void optional(T const ¶m); // or optional(T param)
_
これは、パラメーターの引き渡しがオプションであることを除いて、上記の非変更のケースに関連しています。ここでは、3つの状況すべての違いが最も小さいため、人生を最も簡単にするものを選択してください。もちろん、非constポインタのデフォルト値はあなた次第です。
_void f(T);
void f(T const);
_
これらの宣言は実際にはまったく同じ関数です!値で渡す場合、constは純粋に実装の詳細です。 実際に試す:
_void f(int);
void f(int const) {/*implements above function, not an overload*/}
typedef void C(int const);
typedef void NC(int);
NC *nc = &f; // nc is a function pointer
C *c = nc; // C and NC are identical types
_
一般的なルールは、可能な限りconst
を使用し、必要な場合にのみ省略します。 const
を使用すると、コンパイラーが最適化され、コードがどのように使用されるかをピアが理解できるようになります(コンパイラーは誤用の可能性をキャッチします)。
あなたの例と同様に、C++では文字列は不変ではありません。文字列への非const
参照を関数に渡すと、関数がそれを変更する場合があります。 C++には不変性の概念が言語に組み込まれておらず、カプセル化とconst
を使用してのみエミュレートすることができます(ただし、決して防弾にはなりません)。
@Eamonsのコメントを読み、いくつかのことを読んだ後、最適化がconst
を使用する主な理由ではないことに同意します。主な理由は、正しいコードを持つことです。
質問はいくつかの誤った仮定に基づいているため、あまり意味がありません。
std::string
は、不変の文字列値をモデル化しません。変更可能な値をモデル化します。
「const参照」のようなものはありません。 const
オブジェクトへの参照があります。区別は微妙ですが重要です。
関数引数のトップレベルのconst
は、関数の実装でのみ意味があり、純粋な宣言では意味がありません(コンパイラーによって無視されます)。発信者には何も伝えません。これは実装の制限にすぎません。例えば。 int const
は、関数の純粋な宣言の引数型としてはほとんど意味がありません。ただし、std::string const&
のconst
は最上位ではありません。
const
への参照渡しにより、データの非効率的なコピーを回避できます。一般に、データを関数に渡す引数の場合、値で小さい項目(int
など)を渡し、const
を参照して大きい項目を渡す可能性があります。マシンコードでは、const
への参照を最適化するか、ポインタとして実装することができます。たとえば、32ビットのWindowsでは、int
は4バイトで、ポインタは4バイトです。したがって、引数の型int const&
はデータのコピーを削減しませんが、単純なコンパイラを使用すると、追加の間接参照が導入される可能性があります。
乾杯&hth。、
Constポインターに対するconst参照の主な利点は次のとおりです。パラメーターが必須であり、NULLにできないことは明らかです。逆に、私がconstポインターを見つけた場合、それが参照ではない理由はパラメーターがNULLである可能性があるということです。