このような決定を下す唯一の理由は、構文上の利便性と伝統です。私は2つの違いが何であるか(そしてそうではない)、そして決定を下す際にこれらの違いがどのように関係するのかを示すことによって、なぜ説明しますか。
非メンバーフレンド機能とパブリックメンバー機能の違いは何ですか?あまりない。結局のところ、メンバ関数は隠されたthis
パラメータとそのクラスのプライベートメンバへのアクセス権を持つ通常の関数に過ぎません。
// what is the difference between the two inv functions?
// --- our code ---
struct matrix1x1 { // this one is simple :P
private:
double x;
public:
//... blah blah
void inv() { x = 1/x; }
friend void inv(matrix1x1& self) { self.x = 1/self.x; }
};
matrix1x1 a;
// --- client code ---
// pretty much just this:
a.inv();
// vs this:
inv(a);
void lets_try_to_break_encapsulation(matrix1x1& thingy) {
thingy.x = 42; // oops, error. Nope, still encapsulated.
}
これらは両方とも同じ機能を提供し、他の機能が実行できる機能を変更するものではありません。同じ内部が外部に公開されます。カプセル化の点で違いはありません。私的な状態を変更する友人の機能があるので、他の機能が別々にできることは絶対にありません。
実際、大部分の機能を持つほとんどのクラスを非メンバフレンド関数(仮想関数といくつかのオーバーロード演算子はメンバでなければなりません)として書くことができます。フレンド関数以外の関数がプライベートメンバーにアクセスすることはできません。なぜ私たちはそれをしないのですか?それは99.99%のC++プログラマーのスタイルに反して、それから取られる大きな利点はないからです。
違いは、関数の性質と呼び出す方法にあります。メンバ関数とは、そこからメンバ関数へのポインタを取得できることを意味し、非メンバ関数であるということは、メンバ関数へのポインタを取得できることを意味します。しかし、これはあまり関係ありません(特にstd::function
のようなジェネリック関数ラッパーの場合)。
残りの違いは構文的です。 D言語の設計者は、すべてを統一し、inv(a)
のようなオブジェクトを渡してメンバー関数を直接呼び出すことができ、a.inv()
のように最初の引数のメンバーとしてフリー関数を呼び出すことができると言っています。そして、クラスは突然それが何かのためにひどくカプセル化されていません。
質問の特定の例に対処するには、inv
はメンバーですか、それとも非会員ですか?私はおそらくそれをメンバーにしたいと思います。非stylistically、それは違いをもたらさない。
。 C++ではこれが起こりそうにないのは、現時点では大きな変更ではないため、大きなメリットがないからです。極端な例として、私が上に書いたmatrix1x1
クラスを壊すのは、両方の呼び出しがあいまいであるためです。
おそらく、友人の機能がばらばらに広がっているのではなく、オブジェクトの中に機能のカプセル化が明確に定義されていると思います。 – PherricOxide
関連するhttp://stackoverflow.com/a/7821482/46642 –
私はここでアップフォースにふさわしい答えは、メンバー機能とメンバー以外の友人の間の実際の違いを指摘し、その違いがどのように決定を下すのに役立つかを説明するべきだと思います。それはより多くの/より少ないカプセル化を提供するので、すべてを離れて波動させる。 –