2016-09-18 4 views
2

私はBjarne Stroustrupが書いた優れた本を読んでいました。彼は変数をできるだけ後期に宣言することを推奨しましたが、使用する直前に行うことをお勧めしますが、関数の開始時よりも遅く変数を宣言すること体。代わりに、このような関数本体の開始時の関数本体の開始時よりも関数の後半で変数を初期化するとどんな利点がありますか?

int main() 
{ 
    /* some 
    code 
    here 
    */ 
    int MyVariable1; 
    int MyVariable2; 
    std::cin >> MyVariable1 >> MyVariable2; 
    return(0); 
} 

int main() 
{ 
    int MyVariable1; 
    int MyVariable2; 
    /* some 
    code 
    here 
    */ 
    std::cin >> MyVariable1 >> MyVariable2; 
    return (0); 
} 
+0

ありがとうございました。タイマーがなくなったら、数分で回答を受け付けます。コンパイルやそのようなことがあれば、私はちょうど興味がありました。しかし、それは人間の読みやすさのためだけに判明しました。 –

+2

それは人間の可読性に関するすべてではありません。デフォルト構成と例外に関する私の点を参照してください –

+2

@ハリー・ハッカー:あなたは答えの内容の80%を無視したようです。それらをもっと徹底的に読んで、答えを受け入れることを急いではいけません。 –

答えて

2

これらのオブジェクトのいくつかのオブジェクトを処理すると、高価な操作であるとします。そのような状況では、使用の直前に変数を定義する方が良い理由はいくつかあります。

1)まず、デフォルト構築と代入の代わりに適切なコンストラクタを使用してオブジェクトを作成するほうが速い場合があります。したがって、この第一例では、単一のコンストラクタが呼び出されること

T obj; 
/* some code here*/ 
obj = T(/* some arguments here */); 

T obj(/* some arguments here */); 

が速く、この次にであってもよいです。しかし、2番目の例では、デフォルトのコンストラクタと代入演算子が呼び出されます。

2)オブジェクト定義とその最初の使用の間のどこかに例外がスローされた場合は、オブジェクトを作成せずにオブジェクトを破棄し、まったく使用しないでください。オブジェクト定義とその最初の使用の間に関数が戻るときも同様です。プログラミングが得意取得し始めたとき

3)はい、読みやすさもここで言及する価値がある:)

+1

_ "通常、オブジェクトを作成して同じ時刻に初期化する方が高速です。" - オブジェクトを作成するとき以外のときにオブジェクトを初期化することはできません。 2番目の例は、事後割り当ての例です。パフォーマンスの角度は厳密には間違っているわけではありませんが、違いが実際にどのように顕著であるかについては、特有のデフォルトのコンストラクタが必要です。 –

+0

@LightnessRacesinOrbit素晴らしい発言!ありがとうございました。私は数分で私の答えを調整します。 –

+2

@ハリー・ハッカー私はダビデの答えがはるかに完全であると信じています。私の意見では、彼の答えは受け入れられたとマークする方が良い) –

5

それは従って、コードが容易になり

だから、このように後半の変数を宣言することの利点ものです。一般的に、必要なときに変数を宣言します。そのループを介して何かの最小値を見つけたいときは、ループの近くにあります。このようにして、誰かがあなたのコードを読むとき、彼は関数の始めに25の変数が意味するものを解読しようとする必要はありませんが、コードを通過するときに変数は自分自身を「説明する」でしょう。結局のところ、変数の意味を知ることは重要ではなく、コードが何をするのかを理解することです。

ほとんどの場合、コードのごく一部でそのローカル変数を使用するため、必要な場所でそのローカル変数を定義するのが理にかなっています。

4

"other code"がコードのページである場合、値を読み取ったときに実際に宣言が表示されません。あなたが2つのダブルスを読んでいると思ったら、あなたが間違っていることを画面上で見ることができません。変数を1行に宣言して、それを次の行に使用すると、間違いが明白になります。

+0

これはまた優れた点です! – vsoftco

+2

あなたの機能がこのような長い場合は、既に失敗していることに気をつけてください。 –

+0

@ LightnessRacesinOrbit:それはあなたの意見であり、私は非常に議論の余地があると感じるものです。 – gnasher729

5

  1. ないすべてのオブジェクトがデフォルトです頭に浮かぶいくつかのポイント - 関数の先頭にオブジェクトを宣言構成可能、非常に多くの時間が唯一の割り当てに、オプションではありません(別名auto myObj = creationalfunction();
  2. あなたの関数は、より少ない数の行を得るため、より読みやすくなります。関数の初めに各変数を宣言すると、コード全体で数行が実際に大きくなります。あなたの関数がスローした場合
  3. - それはちょうどスタックアンワインドコードの倍以上になり、彼らはあなたがautoを使用させることができます割り当てられている同じ行に
  4. 宣言した変数を上それらを破壊するために、オブジェクトのリストを構築するために経済的ではありませんフレキシブル。
  5. これはC++の一般的な規約ですが、これはかなり重要です。
  6. オブジェクトを作成して後で割り当てることは、値を持つオブジェクトを直接初期化するよりも遅くなる可能性があります。
+0

すてきな理由!あなたは私が自分の答えで書くことを決めたすべてを言いました:)私からの+1。 –

1

あなたは通常、同時にあなたの頭の中でプログラム全体を保持することになります。後で、これを頭の中の1つの機能に減らす方法を学びます。

これらの両方は、操作できるプログラムまたは機能の大きさ/複雑さを制限します。何が起きているのかを単純化して考える必要がなくなり、作業メモリの必要性を減らすことで、この問題の解決に役立ちます。また、ある種類の複雑さを別のものと交換することもできます。いくつかの複雑な高レベルアルゴリズムのためのfsncy可変値ダンス、またはコード正しさの確からしさ。

これを実行する方法はたくさんあります。チャンク可能なパターンで作業し、下位レベルのプリミティブではなく、それらのパターンで考えることができます(これは基本的に、プログラム全体の状態から単一の関数状態になったときに行ったものです)。状態を簡単にすることでこれを行うこともできます。

すべての変数は状態を保持します。これは、そのコード行が何を意味しているのか、そして前のすべてのコード行はその宣言のポイントまでを意味するものです。行に存在する変数は、行によって変更されるか、行によって読み取られる可能性があります。変数の読み方が何であるかを理解するには、宣言とその使用の間のすべての行を、編集された可能性について監査する必要があります。

これは発生しない可能性がありますが、チェックすると、の両方に時間と作業メモリがかかります。もしあなたが10個の変数を持っていれば、それらのうちのどれが "上"に修正されたのか、また修正されなかったのか、そしてそれらの値が何を意味するのかを覚えなければなりません。

一方、作成され、使用され、範囲外に落ちるか、まったく使用されない変数は、この認知負荷を引き起こすことはありません。隠された状態や意味を確認する必要はありません。それ以上に、あなたはその行の前にそれを使うことはできません。後のコードでは、設定時に依存する重要な状態を上書きするつもりはなく、初期化と使用の間に何か驚くべきものに変更することはありません。要するに

、あなたがそれを使用するコードの行の「状態空間」を減らし、さらにはそれを使用しないでください。

時には、これは達成することは困難で、時には非現実的または不可能です。しかし、しばしば簡単で、コードの品質が向上し、読みやすく理解しやすくなります。最も重要なコードの読者は人間です。コンパイラのオブジェクトファイルの出力(または何らかの中間表現)をチェックしない理由があります。

Suc「低状態」コードも事後に変更するのが簡単です。限界では、それは純粋な機能コードになります。

関連する問題