好 - 如果你想你所描述什麼,然後朋友是最好的解決方案。每個編碼標準建議不要使用朋友,但其他設計更復雜 - 那麼也許值得做個例外。
爲了解決不朋友的問題需要一個不同的體系結構
一種解決方案可以是使用其中「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