どのようにしてconstの正しい変換になりましたか?[閉まっている]


25

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

それでは、どのようにconstの利点を愛するようになりましたか?


3
if constrcutやsizeof演算子などの問題を解決するツールよりも、constの正確性は正しいと思います。
legends2k

9
「constがC ++で機能する理由は、それを捨てることができるからです。それを捨てることができなければ、あなたの世界は吸うでしょう。」-アンダース・ヘイルスバーグ
メイソン・ウィーラー

1
constはC型修飾子でもあり、最初のANSI C標準以来のものです。
Huperniketes

Java / C#に甘やかされている私は、私が得るあらゆる機会を断念することを好む偏執的なタイプです。何がうまくいかないかは、うまくいかないでしょう。コンパイル時または実行時の支援がある場合は、私を考慮してください!私はそれについて3-4回聞いてすぐに改宗者になり、このリンクの一部をたどりました(構文を見るのに十分な理由について読む必要はありませんでした):possibility.com/Cpp/const.html何かが私の顔にまだ吹き飛ばされていないという理由だけで...それはconstを正しくするために少しの努力を必要とし、それは傷つけません。:ジョエルの思考チェックアウトjoelonsoftware.com/articles/Wrong.html
仕事

回答:


28

哲学を受け入れようとするまで、私は納得しませんでした。

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

そこから、私はもうコンパイルできませんでした。その後、これらの基本クラスを使用してコードに取り組み、以前のconst追加が実際にそれらを使用した場合と比較して本当に正当かどうかを確認しました。コードの他の部分に一定性を追加することで、途中でいくつかのバグを修正するのに役立ちました。

伝染性です。ほとんどのコードはより安定しており、デバッグする方が簡単であることがわかりました。これは、修正すべきでないものを変更し始めた場合にコンパイラが停止することを確信できるからです。

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

私は確信しました。

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


8
伝染性の+1は、基本的にconst変換になるか、完全に回避する必要があることを意味します。
マーティンウィックマン

また、constの正当性を行わないライブラリに依存する必要もありません。あなたのアプローチは、constではないのでgui関数を呼び出すことができないことを意味する場合、またはすべてのgui呼び出しでそれを捨てる必要がある場合、機能しません。
マーティンベケット

4
私が使用して、「デバッグにそれが簡単に見つかった」のための+1 const私が上ですくい取ることができ、コード読み取り時に、私は変更する必要はありません知っていることも、ローカル変数のためにこの方法をiffor、私の変数が一定である、私は:またはwhatelseを変わらないことを知ってください!最適化についてはあまり気にすることはできませんでしたが、私は脳が限られており、インデントのレベルが少ない+ const-correctnessは大いに役立ちます!
マチューM.

@MatthieuM .: Haskellへの切り替えを検討したことがありますか?;-)
ジョルジオ

@Giorgio:私はそれを調査しましたが、「Real World Haskell」の購入までも行ってきました。正直に言うと、デフォルトでは怠inessで、興奮している多くの不可解な演算子に興奮していません。
マチューM.

15

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

基本的に、不変状態になり得る正当な理由がない限り、不変である可能性のあるものすべておそらくそうです。私の経験では、この目標を追求して任意の言語でプログラムを作成すると、より安全で優れたコードになります。const該当する場所を使用しても、失うものは何もありません。不変性は無料です。

(ちなみに、const明示的に修飾されていない限り、すべての型がC ++の方言用にGCCのフォークを作成するというアイデアをいじりましたmutable


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

constどこにでも入力するのは面倒ですが、あなたはすぐに慣れてしまい、信頼性と保守性の面で時間の経過とともに利点が明らかになります。私は素晴らしい作家ではないので、それを主張することは証明された難しい仕事のようですが、プログラムの設計と実装の際に開発者としてconstの正確さが非常に役立っていることを知っています。この点で最高の先生。


2
基本的に、constの正確性は良いことだと言っただけです。あなたはそれが「より安全でより良いコードにつながる」と言った。理由を言えますか?
デビッドレイ

私は完全に不変性のキャンプにいます。私の好きな言語はアーランです。しかし、C ++のconstを介した不変性は本当に無料ではないと主張します。読みにくいコード、同じメソッドのconstおよびnon constバージョン、またはconstをキャストすることによる「他の選択肢がなかった」などの欠点があります。
-grok

1
を使用するだけでなくmutable、constの正確性に関して明確な意味を持っていることをお勧めします。つまり、このデータオブジェクトは、オブジェクトの動作に影響を与えない方法で変更でき、回答のキャッシュなどを許可します。別のキーワードを作成します。
デビッドソーンリー

2
@David Thornley:一貫性のため、mutable論理的な選択です。void alter(mutable Point&)同じように、理にかなっているmutable int fooローカル変数のために、そしてどちらも既存の言語や既存の使用とこれらの競合のmutable。また、Object mutable* mutableそれが必要か正しいかについて警告するほど怖いようです。
ジョンパーディ

フォークをする場合、代わりにCLangを使用することを検討してください。
gf

6

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

規律は、どこで何かが変わる可能性があるかを知る必要があるということです。対応する利点は、状態を変更している可能性があるものを特定できる場合に、コードの一部が何をするのかを簡単に確認できることです。


1
「プログラムは、人々が読むために、そして偶然にマシンが実行するためだけに書かれなければなりません。」
-SICP-

4

ビーイングconstの正しいことは、私はキャスト演算子を使用していない同様の問題に近い治療設計の正しさを強調しています。キャストを使用せず、constを正しく使用せず、可変の最小限の使用- これらはすべて、デザインの良さを測定するためのポインターですが、手元の全体的な問題を解決するための実際のツールではありません。

PS:私はそれを使うことの正確さconstを理解すると、完全に確信しました;)



2

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


2

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

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

2

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

  • constAPIのユーザーにコードを文書化します。関数とその呼び出し元の間で、関数がパラメーターを変更しないというコントラクトを形成します。(const_cast関数がそのパラメーターを変更できるようにすることはできませんconst。パラメーターを変更せずに注釈を忘れた他の関数にそのパラメーターを渡すことができます。)ループ不変式と同じ方法。

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

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

これらの2番目は最初に学んだ。constポインターと参照パラメーターのターゲットのみで開始しましたが、エラーを早期に検出してローカルで使用するなどの利点を確認し始めるまでは

その後、ほとんど#defineのsが(C ++で)グローバル定数に置き換えられ、型安全性の利点が追加されることを学びました。そこで私もそれを使用しました。

最後に、型システムとラムダ計算のクラスを取り、型constと非const型が根本的に異なることを学習しました(異なる操作をサポートしているため)。それ以来、const


1

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

同じ原理ですが、constを使用する実際的な理由を追加したかっただけです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.