web-dev-qa-db-ja.com

C ++では、対応するヘッダーでローカル変数を宣言する必要がありますか?

したがって、たとえば、2つの関数を持つクラスを作成します。

foo.h

class foo
{
public:
    foo();
    void bar();
    void ey();
    bool m_memberBool;
    bool localBool; // ??? Should I put this here?
};

foo.cpp

#include "foo.h"

foo::foo() {
    bool m_memberBool = true;
}
void foo::bar() {
    bool localBool = true;
    if (localBool && m_memberBool) {
        ey();       
    }
}
void foo::ey() {
    m_memberBool = false;
}

そのローカル変数、またはヘッダーにローカル変数を含める必要がありますか?そうでない場合は、ヘッダーに文書化する必要がありますか?

2
user2690449

技術的には、あなたの質問に対する正しい答えは、それが言葉の矛盾だということです。変数をクラス定義に上げると、それはローカル変数ではなくなり、メンバー変数になります。

しかし、ローカル変数をメンバー変数のステータスに上げる正当な理由があるかどうかを尋ねていると思います。この質問は、クラスとその変数の目的に帰着します。

一般的な経験則は次のとおりです。すべての変数は可能な限り狭い範囲で宣言する必要があります。つまり、foo :: barのみが使用する必要がある場合に、すべてのfooが使用できる場所で宣言しないでください。コードが実際には必要としない変数にアクセスすることは、一般的には悪い考えです。なぜなら、それらが最終的にdependまたはrely特定の時間に特定の値を持つこれらの変数で、それらの変数を使用して他のすべてのコードに結合し、他の部分を壊さずに一部を変更することを困難にします。

Fooの他のメソッドは実際にこのブール値にアクセスする必要がありますか?そうでない場合は、ローカルにしてください。正当な理由がある場合は、いつでも後でレイズできます。

15
Ixrec

そのローカル変数、またはヘッダーにローカル変数を含める必要がありますか?

私が考えることができる唯一のケースは、インラインまたはテンプレート関数を書く場合です:それらのために、関数/メソッド本体はヘッダーにあるべきです。そして、明らかに、ローカル変数もヘッダーにあります。

そうでない場合は、ヘッダーに文書化する必要がありますか?

まれに、呼び出し元mustが関数のローカル変数について知っている場合があります。例えば。スタックスペースが少なく、関数が100kのローカル配列変数を使用している場合。または、それがテンプレート関数のインスタンスを明白に作成しないテンプレート関数である場合、その情報は呼び出し元にとって重要かもしれません。

しかし、それらは極端で解釈されたEdgeのケースです。一般的なケースでは、ヘッダーは、関数が提供する外部の「契約」、つまり呼び出し元がコードの将来のバージョンでも信頼できる動作のみを文書化する必要があります。

これを尋ねる別の方法は、私が使用している変数が1つの関数でのみ使用されているかどうかです。常にローカル変数にする必要がありますか、またはその変数をメンバーにする必要がある場合はありますか?

@Brandinが言ったように:異なる呼び出し間で状態を保持する必要がある場合は、メンバーにします。

ただし、そのメンバーを分割して別のクラスに機能させ、代わりにそのクラスのメンバーを持たせるほうが、よりクリーンな設計になる場合があります。

class BarState
{
private:
    bool localFlag;
public:
    void Bar();
    // or even:
    void operator()();
};

class Foo
{
    BarState bar;
};

そうすれば、次のことが明らかになります。

  • 「関数」Barは呼び出し間で状態を保持します
  • メンバーlocalFlagBarにプライベートであることが意図されています
1
nikie

Member variablesは、クラスに関連付けられているため、そのクラスのオブジェクトの一部になる値の型です。

Local variablesは、スコープに対してローカルな値ホルダーです。ここでのスコープはfunctionsif conditionsまたはswith case、通常、使用するすべてのもの{}

ここで、どこに置くかを決める必要がある場合は、次の経験則を使用します。

  1. Member variableはクラスの属性です。つまり、クラスオブジェクトのメソッドやマニピュレータによって使用される可能性があります。
  2. Local variableは、操作のためにローカルで、または一時的な値ホルダーとして必要です。つまり、現在のスコープでのみ役立ちます。

お役に立てば幸いです。質問があればコメントしてください。

0
Ravinder