7

これは、C++クラスの実装で何度も出てくる質問です。人々の考えがここにあるのか知りたいです。どのコードが好きですか、そしてその理由は何ですか?

class A
{
public:
    /* Constructors, Destructors, Public interface functions, etc. */ 
    void publicCall(void);

private:
    void f(void);

    CMyClass m_Member1;
};

void A::publicCall(void)
{
    f();
}

void A::f(void)
{
    // do some stuff populating  m_Member1
}

または代替:

class A
{
public:
    /* Constructors, Destructors, Public interface functions, etc. */ 
    void publicCall(void);

private:
    void f(CMyClass &x);

    CMyClass m_Member1;
};

void A::publicCall(void)
{
    f(m_Member1);
}

void A::f(CMyClass &x)
{
    // do some stuff to populate x, 
    // locally masking the fact that it's really m_Member1
}

私は常に2番目のものを好むと思います。なぜなら、その後fは任意のインスタンスで操作できるからですCMyClassが、それでも、最初のコードは完全に有効であるため、fこれまでにのみ操作されるのでm_Member1、実際には2つの関数に分割しています。コードを読みやすくします。

はい、これは「答え」の質問というよりは議論の質問ですが、私は推論にもっと興味があります。私は答えとして、良い推論または良い基準を与える応答をマークします。

また、これは単なるおもちゃの例であることに注意してください。クラスは実際にはこれよりも大きくなるため、組織化が重要です。

4

5 に答える 5

3

あなたが意見を求めているので、スタンドアロンf(CMyClass&)機能が理にかなっていて実装可能であるなら、私もそのオプションを好みます。fによって実行される操作がクラスAのコンテキストでCMyClassのみ意味がある場合、Aのコンテキストでのみ意味がある場合、または。の他の属性に依存する場合は、最初のケースを選択しますA。問題に応じて決めなければならないと思います。

于 2012-03-22T19:19:22.057 に答える
2

いつものように、それは異なります。それぞれのシナリオは異なります。

あなたが与えた特定の例では、最初に私はあなたの代替案()を除外します。void A::f(CMyClass &x)それは主にそれが(マーティン・ファウラーが言うように)悪臭を放つからです。これはプライベート関数であり、他のインスタンスで今すぐ使用する必要がない限り、メンバーを使用するようにします。必要に応じていつでもリファクタリングできます。

2つのパラメータがあるとどうなるか想像してみてfください。3つのパラメータ。10.それでは、毎回送信するのは理にかなっていますか?これらのパラメータメンバーを持っている方が良いのではないでしょうか?

そしてf、これらの引数のいくつかを他のメソッドに送信する必要がある場合はどうなりますAか?これにメンバーを使用する方が理にかなっていますか?

fこれはすべて、保持する他の情報が必要であると想定していAます。そうでない場合は、のメソッドに移動しますCMyClass

于 2012-03-22T19:27:11.393 に答える
1

f()自問してみてください。それ以外のオブジェクトで呼び出すことは、現在意味がありますか、それとも近い将来に意味がありm_Member1ますか?

答えが次の場合:

  • いいえ。の本質的な部分であるf()ように、パラメータなしで実行します。m_Member1A
  • はい。を行いf(CMyClass &)ます。今は、のみを使用している場合でもm_Member1、それは処理するクラスの固有のプロパティではありません。
  • 多分。ええと...私はパラメータなしで行くと思いますf()。あなたの心を変えるオプションは常にあります(実際には、かなり些細な場合の変更)。

f()また、関数は別の関数を呼び出すことができますが、その逆はできないことに注意してくださいg(CMyClass &)。したがって、何をするかによってf()は、オプションが制限される場合があります。

于 2012-03-22T19:19:01.433 に答える
1

2番目の例ではf、静的関数Aまたはグローバル関数、あるいはおそらくのメンバー関数として優れているのではないでしょCMyClassうか。

もちろん、その関数を呼び出すたびに引数を送信したほうがよい場合もありますが、AオブジェクトのCMyClassオブジェクトに既にあるのに、なぜそれを再送信するのでしょうか。CMyClass相互作用するために両方のCMyClassオブジェクトが必要な場合は、にではなく、メンバー関数リストに追加する方がよい場合がありますA

また、Clean Codeが述べているように、引数のある関数よりも、引数のない関数の方が適しています。別のプログラマーが関数を読み込もうとすると、関数名以外の2番目のパラメーターを解読/注意する必要があります。

于 2012-03-22T19:24:11.480 に答える
1

私は文脈に基づいて答えを出します。fが操作する可能性のあるメンバー変数のインスタンスが現在またはいつか複数ある場合は、必ずそれをパラメーターとして渡します。ただし、fがAのインスタンスの状態の特定の要素で動作している場合、私はそれに何も渡しません。Aには常にfooが1つしかない場合がたくさんあります。その時点で、fooをfのパラメーターにするのはばかげています。また、fがインラインでない限り、このポインターが渡されるだけでなく、スタックへの追加コピーであるfooのアドレスも渡されるため、効率が少し低下します。

于 2012-03-22T19:25:20.933 に答える