有没有办法使所有的派生类彼此成为朋友?
Is there a way to make all derived classes friends of one another?
如果是,在什么情况下这可能是有用的?
或者(我想就是这样),为什么它绝对没用?(还有什么其他的方法实质上涵盖了这种友谊所提供的能力,但以一种更安全、更少泄露的方式?)
我几乎认为我需要这样一个东西。最后我采用了一种完全不同的设计,让所有的类成员都是静态的。我还是很好奇
是否有办法使所有的派生类彼此为友?
该语言没有提供任何机制来在基类中指定类似的内容。必须在从基类继承的每个类中提供友元声明。
我不知道你们要解决的问题是什么,所以我不能给出更积极的建议。
在评论中,你说:
在我的例子中,我需要访问兄弟方法,所以如果
B
和C
派生自A
,我需要从C::foo()
调用B::foo()
。在我的例子中,这些类封装了不同的算法(所以我想到了策略模式……),但有时一个算法会使用另一个算法的大量部分。然而,从B
推导出C
似乎是不正确的,因为C
与B
并没有真正的"is-a"关系。
如果C
与B
没有"is-a"关系,但C::foo()
不知何故需要调用B::foo()
,这向我表明B::foo()
只能使用B
和C
共同的数据。在这种情况下,应该可以将代码分解为非成员函数,然后在B::foo()
和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类。任何派生类都可以通过要求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
}
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 派生类销毁的最佳实践是什么
- 如何使用基类指针引用派生类成员
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 存储模板类型以强制转换回派生<T>
- 需要从 istream 和 ostream 派生 iostream
- 在 C++ 中用派生类型重写成员函数
- 具有多个类、派生类的C++正向声明
- 朋友超载的派生类和基本成员访问的运营商
- 朋友功能是否继承?为什么基类朋友功能在派生的类对象上工作
- 派生类的朋友可以访问哪些变量
- 如何使参数化的基础成为 CRTP 中派生的朋友
- 有没有办法使所有的派生类彼此成为朋友?