web-dev-qa-db-ja.com

C ++の非オプションポインターと非const参照

Google C++スタイルガイドその他のC++機能、参照引数 で、非const参照は使用しないでくださいと読みました。

参照によって渡されるすべてのパラメーターには、constというラベルを付ける必要があります。

引数として参照を使用する関数呼び出しを確認することは、Cプログラマーにとって完全に混乱することは明らかですが、現在、CとC++は異なる言語です。出力パラメーターがrequiredの場合、必要な出力パラメーターへのポインターを使用すると、関数本体全体がスキップされ、関数の実装がより複雑になります(以前は循環的複雑度関数の深さ)。

C++コードをできるだけ簡単に理解/維持できるようにしたいので、一般的にコーディングスタイルガイドを読みたいと思います。しかし、チームのベストプラクティスを採用するには、スタイルガイド要素の背後にある理論的根拠を理解することが重要な要素だと思います。

非const参照は本当に悪いのですか?それらを禁止するのはGoogle固有のものだけですか、それとも一般に受け入れられているルールですか?出力パラメーターをポインターとして実装するための余分な労力を正当化するものは何ですか?

12
Wolf

Googleのスタイルガイドの背後にある理論的根拠は、パラメーターが入力パラメーターか出力パラメーターかを関数の呼び出しサイトから明確にすることです。 (詳細については ここ を参照してください。)他の言語では、設計により明示的にパラメーターを作成しています。たとえば、C#にはoutキーワードがあります 呼び出しサイトで使用する必要があります 。 C++はそれを明示的にしないので、Googleはconst refを使用することを選択しました。明確にするためのポインタとの比較。

これは単なるGoogleのルールですか?いいえ、しかし、それが非常に広まっているとは思えません。 Googleのスタイルガイドや、Googleのスタイルガイドの一部に明示的に固執するグループ以外では見たことがないと思います。 (たとえば、私が何年も前に最初にGoogleスタイルガイドを読んだときのアイデアが気に入り、自分のコードの一部にそれを使用しました。)

特に、新しく発表された C++コアガイドライン は、(ほとんど)すべての出力パラメーターよりも戻り値を優先し、残りには非const参照を使用します。 Googleのポインターと参照の使用により、出力パラメーターがより明確になる場合がありますが、戻り値はさらに明確です。 C++ 11の動きが標準化された(右辺値参照、&&、多くのタイプの戻り値を安価にする)およびタプル(複数の値を返す簡単な方法を可能にする)のために、outパラメーターの多くの使用例は適用されなくなりました。

C++コアガイドラインにはいくつかのビッグネーム(Bjarne Stroustrup、Herb Sutter)があり、Microsoftによってサポートされており、最新のC++機能(Googleのスタイルガイドとは異なります)を採用しているため、推奨事項はGoogleよりも人気があると思います。

18
Josh Kelley

渡された無効なポインターを処理するには、最初のチェックと早期復帰、またはそれを未定義の動作にする2つのオプションがあります(堅牢性よりも速度を重視する場合)。

チェックは次のように簡単です。

void foo(void* buffer){
    if(buffer == nullptr)
        return;

    //actually foo

    // note no increase in indentation required

}

このタイプのチェックは、一般にパラメーターチェックとして受け入れられます。コードを見ると、null以外のポインタが渡され、渡されない場合は早く戻ることが予想されることは明らかです。これにより、無効なポインターについてそれほど心配する必要がなくなります。

1
ratchet freak

それはあなたの観察に帰着しますIf an output parameter is required

関数のシグニチャーが出力パラメーターを持つ必要がある唯一の場所は、外部APIによって指定された場合です。そのような場合は、常に有効な指示先が確実に存在するように外部APIをラップするだけです。

内部的には、戻り値の型をすべての「outs」の複合になるように拡張することにより、出力パラメーターを回避します

1
Caleth