2009-07-17 8 views
13

私はクラスを持っています。これは便利なクラスです。とても好きです。それをMyUsefulClassとしましょう。 MyUsefulClassにはパブリックメソッドがあります。それをprocessUsefulData(std::vector<int>&)としましょう。C++クラスの "ヘルパー関数"はメンバ、フリー、またはanon-namespaceを解放する必要がありますか?

processUsefulDataは実際には2つのことを行い、私はこのことから、それをリファクタリングしたいとします

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data) 
{ 
    for (/*...*/) 
    { 
     for (/*...*/) 
     { 
      // a bunch of statements... 
     } 
    } 

    for (/*...*/) 
    { 
     for (/*...*/) 
     { 
      // a bunch of other statements... 
     } 
    } 
    return data; 
} 

、私はこれらの責任を分割し、そう

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data) 
{ 
    doProcessA(data, dataMember_); 
    doProcessB(data, otherDataMember_); 
    return data; 
} 

ように、コードを書き換えたい、私は2つのヘルパー関数を自由な関数またはメンバ関数にする必要があるかどうか、それぞれが適切であるかどうかは分かりません。私は匿名の名前空間でそれらを作る方が良いかどうかもわかりません。誰もこれを行う良い時を知っていますか?

+0

このように一般化すると、良い答えが得られません。それぞれの状況は、あなたがやっていることに依存しています。 –

答えて

7

フリー機能/メンバ関数

私はそれらを自由に機能するだろう(彼らはクラスの内部へのアクセスを必要としない)ことも可能です。彼らが一連の属性に対して作業する場合、または他のメンバーへのアクセスが必要な場合は、それをメンバー関数にします。

アクセス

コードは、この範囲では意味を持ち、そしてプライベートそれらを作る、他のコードから使用されることはありません場合は、次の場合は、民間それがメンバーである場合、または無名の名前空間に実装それは自由な関数です。

コードを使用することで他のコードが有効になる場合は、そのコードをインターフェイスに公開します。つまり、メンバである場合、または名前付き名前空間(またはグローバル名前空間)のヘッダを介して自由な関数にアクセスできるようにする場合、保護されます。

3

私は通常、protectedまたはprivateメンバー機能を作成します。クラスを導出し、関数をオーバーライドするかどうかによって異なります。

他のクラスで使用されている一般的な機能の場合は、共通クラスまたはクラスが使用する別のオブジェクトに含まれる静的関数に移動します。

0

範囲について考えてみましょう。これらの機能は別のクラスで使用されるのでしょうか、それとも他の場所で使用されるのでしょうか?彼らは公的に通話可能であるべきか?

私の個人的なメンバー機能のようですが、全体的なスコープ構造によって異なります。

2

メンバー機能より常に自由な機能を優先します。 なぜ私の答えhereを参照してください。

+0

実際にあなたの他の答えには直接的な説明が含まれていません;-) – Simson

+2

@Simson - 楽しいことに、読者を[このブログの投稿](http://www.gotw.ca/publications/mill08.htm)読者を[この前の投稿](http://www.gotw.ca/publications/mill02.htm)に戻します。幸いにも私たちの健全性のために、その投稿はこのSO投稿に私たちを参照しません(ただし、最初のブログ投稿を参照しています)。 –

0

元の関数がメンバ関数として意味を持つ場合、メンバは確実に機能します。

IMHOは、その機能がどのように使用されているかによって異なります。元の関数の操作が依然として必要であり、リファクタがコードクリーナーを作成するだけの場合は、それらを保護または非公開にして通常関数から呼び出します。あなたはリファクタリングを取得しますが、クラスのパブリックインターフェイスはそのままそのまま維持します。

2

あなたが自由な機能について言及しているという事実は、「他のステートメントの束」がクラスデータへのアクセスを必要としないと信じさせる。もしそうなら、それらを自由にしなさい。これにより、クラスヘッダーの複雑さが軽減され、標準のアルゴリズムではフリー関数が使いやすくなります(おそらく、ベクトルを使用しているのでstd :: for_each?)。

10

可能であれば、通常、ヘルパールーチンを無関係な名前空間に「フリー」ルーチンにします。そうすれば、私は、クライアントが心配する必要のないインターフェース(* .hファイルの外)を複雑にすることはありません。

ただし、これを行うことで非リエントラントを導入しないように注意する必要があります。たとえば、クラス・メンバではなく、グローバル・データ・オブジェクトまたは静的ローカルを変更することによって実現できます。あなたがそれを行う必要がある場合、あなたはそれを適切なクラスのメンバーにする方が良いです。

+0

+1インターフェイスをきれいに保つための良い点! – math

関連する問題