public
C++ には、誰でも呼び出すことができるメンバーと、すべてのメンバーを特定の外部クラスまたはメソッドに公開するが、特定のメンバーを特定の呼び出し元に公開するための構文を提供しないfriend
宣言があるのはなぜですか? private
私は、既知の呼び出し元によってのみ呼び出されるいくつかのルーチンとのインターフェースを表現したいと考えています。それらの呼び出し元に、すべてのプライベートへの完全なアクセス権を与える必要はありません。私が思いつくことができる最高のもの(以下)と他の人による提案は、さまざまな間接性のイディオム/パターンを中心に展開しています。ここで、どの呼び出し元を明示的に示す単一の単純なクラス定義を持つ方法が本当に欲しいだけです(私よりも細かく)、私の子供、または絶対に誰でも)どのメンバーにアクセスできますか。以下の概念を表現する最良の方法は何ですか?
// Can I grant Y::usesX(...) selective X::restricted(...) access more cleanly?
void Y::usesX(int n, X *x, int m) {
X::AttorneyY::restricted(*x, n);
}
struct X {
class AttorneyY; // Proxies restricted state to part or all of Y.
private:
void restricted(int); // Something preferably selectively available.
friend class AttorneyY; // Give trusted member class private access.
int personal_; // Truly private state ...
};
// Single abstract permission. Can add more friends or forwards.
class X::AttorneyY {
friend void Y::usesX(int, X *, int);
inline static void restricted(X &x, int n) { x.restricted(n); }
};
私はソフトウェア組織の第一人者ではありませんが、言語のこの側面では、インターフェイスのシンプルさと最小特権の原則が直接対立しているように感じます。私の希望のより明確な例は、、、またはインスタンス/メンバーメソッドのみがそれぞれ呼び出しを検討する必要があるおよびPerson
のような宣言されたメソッドを持つクラスです。主要なインターフェイスの側面ごとに 1 回限りのプロキシ クラスまたはインターフェイス クラスが必要になるのは、私にはよくありません。takePill(Medicine *)
tellTheTruth()
forfeitDollars(unsigned int)
Physician
Judge
TaxMan
Drew Hallからの回答: Dr Dobbs - Friendship and the Attorney-Client Idiom
上記のコードは、もともと「弁護士」ではなく「プロキシ」というラッパー クラスを呼び出し、参照の代わりにポインターを使用していましたが、それ以外は Drew が見つけたものと同等でした。(あまり自分を責めないでください...) パラメータの転送を示すために、'restricted' の署名も変更しました。このイディオムの全体的なコストは、パーミッション セットごとに 1 つのクラスと 1 つのフレンド宣言、セットの承認された呼び出し元ごとに 1 つのフレンド宣言、およびパーミッション セットごとに公開されたメソッドごとに 1 つの転送ラッパーです。以下のより良い議論のほとんどは、非常によく似た「キー」イディオムが直接的な保護を犠牲にして回避する転送呼び出しのボイラープレートを中心に展開しています。