如果是这样,在什么情况下这可能有用?
或者(我想是这种情况),为什么它绝对没用?(还有什么其他方法基本上涵盖了这种友谊所提供的能力,但以一种更安全、更少泄露的方式?)
我当时几乎认为我需要这样的东西。最后我追求了一个完全不同的设计,使所有的类成员都是静态的。不过我还是很好奇。
如果是这样,在什么情况下这可能有用?
或者(我想是这种情况),为什么它绝对没用?(还有什么其他方法基本上涵盖了这种友谊所提供的能力,但以一种更安全、更少泄露的方式?)
我当时几乎认为我需要这样的东西。最后我追求了一个完全不同的设计,使所有的类成员都是静态的。不过我还是很好奇。
有没有办法让所有派生类成为彼此的朋友?
该语言不提供任何机制来在基类中指定类似的内容。您必须在从基类继承的每个类中提供友元声明。
我无法提出更积极的建议,因为我不知道您要解决的问题。
在评论中,你说:
就我而言,我需要访问同级方法,所以如果
B
并C
派生自A
,我需要调用B::foo()
fromC::foo()
。在我的情况下,这些类封装了不同的算法(因此想到了策略模式......)但有时一种算法会使用另一种算法的大部分。C
然而,从派生似乎并不正确B
,因为C
与 并没有真正的“is-a”关系B
。
如果C
与 没有“is-a”关系B
,但C::foo()
不知何故需要调用B::foo()
,这向我表明B::foo()
只能使用B
和共有的数据C
。在这种情况下,应该可以将代码分解为非成员函数,然后从B::foo()
and中使用它C::foo()
。
将依赖项更改为:
B::foo()
^
|
C::foo()
至
<some namespace>::foo()
^
|
+-------+---------+
| |
B::foo() C::foo()
C++ 只给你两种命名朋友的方法:
friend class C; // a specific class
template <typename T>
friend class S; // friend the class template S
没有办法在其中插入元函数,假设看起来像这样:
template <typename T>
friend enable_if_t<std::is_base_of<Base, T>::value, T>;
但我想如果你对可怕的黑客持开放态度(这个短语应该被解释为永远不要这样做,请上帝不,但它至少有点有趣),你可以简单地将所有派生类型实现为某个模板的显式特化。
struct Base { ... };
template <typename > class Derived;
struct A_tag { };
template <>
class Derived<A_tag> : Base {
template <typename T>
friend class Derived;
...
};
using A = Derived<A_tag>;
如果我们对 , 等做类似的事情B
,C
那么A
,B
和C
相互都是朋友 - 因为在幕后他们真的是Derived<A_tag>
, Derived<B_tag>
,Derived<C_tag>
因此朋友类模板语句涵盖了所有这些。
不friend
完全是,但您可以使用密码模式的某些变体来限制访问
如果您在基类中创建受保护的内部 Passkey 类。然后,任何派生类都可以通过要求 Passkey 作为参数来限制对兄弟的访问:
class A {
protected:
class Passkey {};
};
class B : public A {
public:
void someProtectedFunction(Passkey) {};
};
class C : public A {
public:
void somePublicFunction() {
B b;
b.someProtectedFunction(A::Passkey{});
}
};
int main() {
C c;
c.somePublicFunction();
B b;
//b.someProtectedFunction(A::Passkey{}); // error: `class A::Passkey` is protected
}