web-dev-qa-db-ja.com

フリー機能vsメンバー機能

プライベートクラスのメンバー関数にパラメーターがなく、メンバー変数に直接アクセスするのとは対照的に、無料の関数(匿名の名前空間にあり、単一のソースファイルでのみアクセス可能)を持ち、すべての変数をパラメーターとして送信することの利点は何ですか?ありがとう!

ヘッダ:

 Class A {
    int myVariable;
    void DoSomething() {
       myVariable = 1;
    }
 };

ソース:

 namespace {
    void DoSomething2(int &a) {
        a = 1;
    }
 }

 int A::SomeFunction() {
    DoSomething2(myVariable); // calling free function
    DoSomething(); // calling member fucntion
 }

それらをメンバーにしたい場合は、最初にメンバー変数にアクセスしていない関数を呼び出したが、その関数がメンバーにアクセスしている別の関数を呼び出す場合はどうなりますか。それらは両方ともメンバー関数であるか、無料である必要がありますか?

18
Jana

ソースファイル内の非メンバー関数の利点の1つは、 Pimplイディオム の利点と同様です。実装を変更した場合、ヘッダーを再コンパイルする必要はありません。

_// widget.h
class Widget 
{
public:
    void meh();
private:
    int bla_;
};

// widget.cpp
namespace {
    void helper(Widget* w) // clients will never know about this
    { /* yadayada */ }
}

void widget::meh() 
{ helper(this); }
_

もちろん、このように記述した場合、helper()Widgetのパブリックインターフェイスしか使用できないため、ほとんど利益が得られません。 helper()friend宣言をWidget内に置くことができますが、ある時点で、本格的なPimplソリューションに切り替える方がよいでしょう。

12
TemplateRex

この質問を参照してください: 有効なC++項目23メンバー関数よりも非メンバー非フレンド関数を優先する および C++メンバー関数とフリー関数

疎結合を促進する範囲で、自由関数を優先する必要があります。

それが機能する場合にのみメンバー関数にすることを検討してくださいクラスの内臓で、そしてそれが本当にあなたのクラスに結びついているとあなたは考えます。

それは本の要点です101 C++コーディング標準、メンバー関数よりも自由関数と静的関数を好むと述べています。

これは意見に基づいていると見なされるかもしれませんが、クラスをほとんど維持せず、懸念を分離することができます。

この answer は、次のように述べています。「このルールの理由は、メンバー関数を使用すると、誤ってクラスの内部に依存しすぎる可能性があるためです。」

11

フリー関数とメンバー関数の主な利点は、インターフェイスを実装から切り離すのに役立つことです。例えば、 std::sortは、それが動作する基礎となるコンテナーについて何かを知る必要はありません。ただ、提供するコンテナーへのアクセスが(イテレーターを介して)与えられているだけです。特定の特性。

あなたの例では、DoSomething2メソッドは、参照によって渡されることによってプライベートメンバーにアクセスする必要があるため、カップリングを減らすことはあまりありません。代わりに、単純なDoSomethingメソッドで状態の変更を行う方がほぼ確実です。

クラスのパブリックインターフェイスの観点からタスクまたはアルゴリズムを実装できる場合は、無料の関数を作成することをお勧めします。スコットマイヤーズはここに合理的なルールのセットを要約しています: http://cpptips.com/nmemfunc_encap

6
Mark B