为什么 C++ 有public
任何人都可以调用的成员和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
具有声明方法的类,例如takePill(Medicine *)
tellTheTruth()
,forfeitDollars(unsigned int)
只有Physician
、Judge
或TaxMan
实例/成员方法,甚至应该分别考虑调用。每个主要接口方面都需要一次性代理或接口类让我感到不舒服,但如果你知道我遗漏了什么,请说出来。
Drew Hall接受的答案:Dr Dobbs - Friendship and the Attorney-Client Idiom
上面的代码最初将包装类称为“代理”而不是“律师”,并使用指针而不是引用,但在其他方面与 Drew 发现的相同,然后我认为这是最广为人知的解决方案。(不要太用力地拍自己的背……)我还更改了“restricted”的签名来演示参数转发。这个习惯用法的总成本是每个权限集一个类和一个朋友声明,每个批准的调用者一个朋友声明,每个权限集每个公开的方法一个转发包装器。下面大多数更好的讨论都围绕着转发呼叫样板,一个非常相似的“关键”习语以较少的直接保护为代价避免了这种样板。