11

constプリミティブ型を扱う修飾子に注意を払う必要がありますか? どちらがより構文的に正しいですか?またその理由は?

最初のバージョン:

float Foo::bar(float a, float b)
{
    return (a + b) / 2.0f;
}

2 番目のバージョン:

const float Foo::bar(const float a, const float b)
{
    return (a + b) / 2.0f;
}

3 番目のバージョン:

float Foo::bar(const float a, const float b)
{
    return (a + b) / 2.0f;
}

メソッドに渡すときにプリミティブ型の変数がコピーされることは知っていますが、より明確な方法は何ですか?

4

5 に答える 5

4

まず、提供する定義はすべて構文的に正しいです。それらがコンパイルされる場合、それらは構文的に正しいです。

パラメーターのconst修飾子の目的は 1 つだけです。それは、関数本体が修飾されたconst引数を変更するのを防ぐことです。

コード例の特定のケースでは、メソッドFoo::barは引数を変更しないため、const修飾子を使用しても何の効果もありません。

ただし、constすべての場合にデフォルトで使用し、変更を許可する状況でのみ削除することをお勧めします。したがって、これを のパラメーターに適用することをFoo::barお勧めします。多少のノイズが発生し、可読性が低下する可能性があるため、めったに使用しないことは認めますが、これは良い習慣だと思います。

考慮すべきもう1つのことは、プリミティブ型、またはより正確にはポインターではないかポインターを含まない型の場合、値によって渡される(つまり、参照によって渡されない)引数を変更しても、副作用はありません。これらの型のパラメーターは実際に機能します初期化されたローカル変数として (これは便利ですが、混乱を招く可能性があります)。ポインターの場合、ポイントされたデータの変更は外部に漏れます。これは、ポインターとtype のポイントされた部分のconst両方で修飾子を使用するもう 1 つの正当な理由です。

全体constとして、可能な限り修飾子を使用すると、コードのエラーが発生しにくくなり、コンパイラが結果のプログラムを最適化するのにも役立ちます。

ただし、これらの型の参照を使用しても、これらの型が CPU レジスタに適合する値を記述している場合 (一般的にはそうです)、大きな変更を行うべきではありません。

したがって、メソッドの 3 つのバージョンはすべて、生成された同じアセンブリ コードになります。

プリミティブな戻り型の特定のケースでは、それは問題ではありません。戻り値は、修飾された値に前後に変換できますconst

const他の人は、関数自体に対する修飾子の関心についても言及しています。Foo::bar元の質問の範囲外ですが、可能であれば ( for のように) 関数を として修飾する方が実際に優れているとも言いconstます。

于 2013-04-16T10:17:11.780 に答える