好 - 如果你想你所描述什么,然后朋友是最好的解决方案。每个编码标准建议不要使用朋友,但其他设计更复杂 - 那么也许值得做个例外。
为了解决不朋友的问题需要一个不同的体系结构
一种解决方案可以是使用其中“B”从内实现对象导出pImpl idiom的一种形式,而其它客户端从外类派生。
另一个可能是在'A'和'其他客户端'之间放置一个额外的继承层。例如:
class A {
public:
void foo();
void bar();
};
class B : public A { // OK access to both 'foo' and 'bar'
};
class ARestricted : private A {
public:
inline void foo() { A::foo(); }; // Forwards 'foo' only
};
但是,该解决方案仍然存在问题。 'ARestricted'不能转换为'A',所以这需要由'A'的其他“吸气剂”来解决。但是,你能说出这样这个功能,因为它不能被意外地叫:
inline A & get_base_type_A_for_interface_usage_only() { return *this; }
想尝试其他的解决方案,并假设您的层次结构必须为你描述后,我建议你只使用朋友!
编辑:因此xtofl建议将类型'A'重命名为'AInternal'和'ARestricted'为'A'。
这很有效,但我注意到'B'不再是'A'。然而,AInternal可以被虚拟地继承 - 然后'B'可以来自'AInternal'和'A'!
class AInternal {
public:
void foo();
void bar();
};
class A : private virtual AInternal {
public:
inline void foo() { A::foo(); }; // Forwards 'foo' only
};
// OK access to both 'foo' and 'bar' via AInternal
class B : public virtual AInternal, public A {
public:
void useMembers()
{
AInternal::foo();
AInternal::bar();
}
};
void func (A const &);
int main()
{
A a;
func (a);
B b;
func (b);
}
当然现在你有虚拟基地和多重继承!嗯....现在,是比单朋友声明更好或更差?
请问你能写出为什么你需要这种方式吗? – 2009-02-02 18:49:00
那么,代码示例说明了为什么你需要它的语法,而不是为什么你需要它在设计方面。对于这样一个小事情,朋友做它应该做的事情。有多少派生类需要朋友访问? > 1? – gimpf 2009-02-02 21:45:05