web-dev-qa-db-ja.com

どのようにしてconstの正当性の変換になりましたか?

15年間のC++を経て、私はまだconstを使うことを愛することを学んでいません。私はそれが使用されていることを理解していますが、実際に const correct になると、私が直面していた問題を回避できるような状況に陥ったことはありません。

では、どのようにしてconstのメリットを気に入ったのですか?

25
grok

ええと、私は哲学を受け入れようとするまで確信が持てませんでした。

最初に、constを、最も基本的なクラスメンバーとメンバー関数引数の本当に読み取り専用のメンバーに配置することから始めました。

そこから、もうコンパイルできませんでした。次に、これらの基本的なクラスを使用してコードを実行することに精通しました。以前のconstの追加が、私が行った使用と比較して本当に合法であったかどうかを確認します。コードの他の部分に一貫性を追加する途中で、いくつかのバグを修正するのに役立ちました。

それは伝染性です。ほとんどのコードはさらに安定しており、不要なものを変更し始めた場合にコンパイラーが停止することを確信できるので、デバッグが容易であることがわかりました。

アプリケーションを再度実行すると、バグが少なくなり、コードを読むときに理解しやすくなり、より高速になりました(発見したいくつかのアルゴリズムを変更する必要がありました)。

私は確信していた。

新しいコードを書いたり、現在のコードを変更したりする必要があるときに自信が持てるので、constnessに加えて多くのアサーションを使用している場合はさらに良いと思います。コンパイラーが必要に応じて停止することを知っています。これにより、変更してはならないすべてのものをチェックする必要がなくなり、ビジネス固有の思考やアーキテクチャ的思考のための思考時間を増やすことができます。

28
Klaim

私はオブジェクト指向プログラミングの支持者になったことは一度もありません。私が成長していないとすれば、プログラミング全般について学ぶほどです。私はさまざまなプログラミングパラダイムを研究してきましたが、不変性はプログラム設計のthe中心的な概念の1つであり、anyの哲学に従って作成されたソフトウェアに影響を与えることに気づきました。これは、関数型プログラミングでは非常に重要であり、単純な安全性の保証に加えて、最適化と同時実行性にも影響します。

基本的に、変更可能な状態の正当な理由がない限り、おそらく不変である可能性があるすべてのものすべきである必要があります。私の経験では、この目標を追求してany言語でプログラムを書くことは、より安全なbetterコードにつながります。該当する場合はconstを使用して失うものは何もありません。不変性は無料です!

(ちなみに、constとして明示的に修飾されていない限り、すべての型がmutableであるC++の方言用にGCCのフォークを作成するというアイデアに興味をそそられました。そのようなものに対するサポートがある場合、私は完全にそれを維持し、使用することを約束します。)


OOの観点から見ると、不変性は無制限の書き込みアクセスを防止することでカプセル化を強制します。不変オブジェクトは独自の状態を完全に管理し、通常の値のように動作する必要があるため、クラス間の結合を軽減します。constの正確さはプロセスを大幅に容易にします特に並行プログラミングのコンテキストで、プログラムの正確さを証明する方法です。C++参照およびC++ 0x右辺値参照セマンティクスを使用すると、不変オブジェクトをどこにでもコピーするオーバーヘッドを心配することなく使用できます。さらに、コンパイラーはほとんど不変のオブジェクトで作業している場合は、かなり驚くべき最適化マジックを実行します。

どこでもconstと入力するのは面倒ですが、すぐに慣れると、信頼性と保守性の面で利点が明らかになります。私は優秀な作家ではありません。それを立証するのは難しいことが証明された難しい仕事のようですが、プログラムを設計および実装するときに、開発者としてconstの正確さが非常に役立つことを知っています。この点で最高の教師。

15
Jon Purdy

Constの正確さの利点は、プログラムに規律を課し、プログラムの一部について推論しやすくなることです。

この分野では、何かが変更される可能性のある場所を知る必要があります。対応する利点は、何が状態を変更しているのかを知ることができるときに、コードの一部が何をするのかを簡単に確認できることです。

6
David Thornley

const正しいことは、デザインの正確さを強調します。これは、キャスト演算子を使用していない同様の問題に近いところで扱います。したがって、キャストを使用せず、constが正しく、変更可能な最小限の使用法-すべてこれらは、デザインがどの程度優れているかを測定するためのポインタですですが、手元の全体的な問題を解決する実際のツールではありません。

P.S.:正確さを理解したら、constを完全に確信しました;)

4
legends2k

私はそれが可能であると知ってすぐに改宗者でした。 「良いプログラミングスタイル」の観点からは、これは理にかなっています。 constが正しいことが望ましいのには、さまざまな理由があります。

  • 読みやすさと理解。他の誰かのコードを読んでいて、関数がパラメーター参照としてconst参照を受け取る場合、そのパラメーターは読み取り専用変数としてのみ使用されることを意図していることを知っています。これは、コードがマルチスレッド環境の場合は特に、大きな勝利です。
  • コンパイラーはconst修飾子を使用して、最適化パスを支援できます。
  • クラスAのオブジェクトを変更したくない状況にあるとします。次に、そのオブジェクトに対して呼び出すことができる唯一のメンバー関数は、constのものです。
2
sashang

Const-correctコードを書く主な理由は2つあります。 1つは、コンパイラが友だちであるということです。constを使用すると、潜在的なバグを警告することができます。 2番目の理由は、const-correctionによりコードが読みやすくなるためです。たとえば、どの関数の引数が入力でどれが出力であるかは常にわかります。また、オブジェクトを変更するメンバー関数と変更しないメンバー関数もわかります。これらのことは、コードを読まなくてもすぐにわかります。もちろん、これはconst_castの非常に賢明な使用を前提としています。

2
Dima

他の回答でカバーされている2つのポイントを要約し、新しいものを追加するには:

  • constは、APIのユーザーにコードを文書化します。これは、関数とその呼び出し元との間のコントラクトを形成し、関数はそのパラメーターを変更しません。 (その点に注意してください const_castは、関数がそのパラメーターを変更することを可能にしません。パラメーターを変更しないがconstアノテーションを忘れた他の関数にそのパラメーターを渡すことができます。)関数/ループ/などでも役立ちます。ループ不変式とほとんど同じ方法で理解を助けます。

  • constは、コンパイラへの意図を文書化します。コンパイル時に間違いを見つけることは、そのコードが実行されるのを待つよりも常に優れています。

  • constは、タイプセーフなポリモーフィズムに必要です。ポインター(生のポインターだけでなく、すべての形式)がconstである場合のみ共変です(注:「constへのポインター」と同じではありません)。共分散には読み取り専用インターフェースが必要であり、反変には書き込み専用インターフェースが必要です。

これらの2番目は、最初に学びました。私は、ポインタと参照パラメータのターゲットでのみconstを使用して始めました。エラーを早期にキャッチし、ローカルなどで使用することの利点を見つけ始めるまでです。

その後、ほとんどの#definesは(C++では)グローバル定数に置き換えることができ、タイプセーフの利点が追加されます。そこで私もそこで使用しました。

最後に、型システムとラムダ計算のクラスを取り、const型と非const型は(異なる演算をサポートしているため)基本的に異なることを学び、それ以来、 constを多用せずにC++コードを記述することを検討しました。

2
Ben Voigt

これは、他の人が言及しているのを見たことがない私の5セントです。変数を渡すとき、本当に必要な場合を除いて、余分な構造や破棄、コピーを回避するために、値で渡す必要はありません。したがって、実際に値で渡す必要がない限り、渡された値を変更するつもりがない場合でも、どこでも参照を使用すると、パフォーマンスが大幅に向上します。このため、すべての引数の参照を取得する関数がある場合、関数が変更しないものを呼び出し元に通知する必要があります。

同じ原則ですが、constを使用する実際的な理由を追加したいと思います。

1
Nikiforos Rotas