在什麼樣的情況下我們會聲明一個成員函數作爲「朋友函數」?確切的目的是否定'OOP函數'的核心概念之一是OOP的'Encapsulation'服務?在什麼情況下應該宣佈一個成員函數的朋友?
回答
你會使用朋友函數的原因是你會使用一個朋友類,但在一個成員函數(而不是整個類)的基礎上。一些很好的解釋在this thread。
雖然朋友功能和類確實違反封裝,但在某些情況下它們可能很有用。例如,您可能希望允許測試工具訪問課程內部,以便您進行白盒測試。您可以打開一個特定的函數來訪問測試工具所需的內部,而不是打開整個類到測試工具。雖然這仍然違反封裝,但比開放整個班級風險更小。
另請參閱this article瞭解關於朋友類和功能的更多信息。
有時,公共/私人/受保護的保護級別對於現實世界的情況還不夠。因此,我們給出了一個小的退出條款,可以幫助您無需公開訪問方法。
我個人使用這種方式與Java使用「包」保護級別的方式相同。
如果我在需要訪問的相同包中有一個類,我會考慮使用朋友。如果它是另一個包中的一個類,那麼我會想知道爲什麼這個其他類需要訪問並查看我的設計。
有時朋友在語法上是更好的(例如,在Fred類,友元函數允許弗雷德參數是第二,而成員要求它是第一個)。朋友函數的另一個好用處是二進制中綴運算符。例如,如果你想允許aFloat + aComplex(成員函數不允許提升左手參數,那麼aComplex + aComplex應該被定義爲朋友而不是成員),因爲這會改變對象的類,成員函數調用的接收者)。
當您嘗試構建必須物理上跨越多個C++類或函數的抽象或接口時,朋友函數和類不會違反封裝!這就是爲什麼朋友被髮明的原因。
這些類型的案例並不經常出現,但有時您會被迫實施具有不同類別和功能的抽象或接口。典型的例子是實現某種類型的複數類。非會員運營商職能與主要複雜號碼類別有友誼。
我還記得在C++中使用CORBA編程時要這樣做。 CORBA迫使我有單獨的類來實現CORBA僕人。但是對於我們軟件的特定部分,我需要將它們作爲一個界面結合在一起。友誼允許這兩個班級一起工作,爲我們軟件的一部分提供無縫服務。
能夠將另一個班級的特定成員功能標記爲班級的朋友可能看起來更陌生,但這只是嚴格控制友誼的一種方式。而不是讓整個其他班級成爲你的朋友,你只允許其中一個成員函數訪問。再次,這並不常見,但很有用當你需要它時很有用。
有一點我認爲是相關的:成員類可以訪問包含類的私有部分。這有時可能是「朋友」的更好選擇。
class A
{
private:
int b;
public:
class MemberNotFriend {
public:
static void test() {
A a;
a.b = 0;
}
};
};
void test()
{
A::MemberNotFriend::test();
}
下面是我如何使用友元函數的簡單,具體的例子:
我有一個遊戲,每個精靈對象存儲像X,Y位置作爲私有成員的信息。但是,我希望將遊戲對象與渲染分開:遊戲對象不需要渲染它的具體細節。遊戲對象僅存儲遊戲狀態,並且該遊戲狀態可以以多種不同方式呈現。
因此,遊戲對象類有一個朋友函數:render()。 render()函數在遊戲對象類之外實現,但它可以根據需要訪問X,Y位置位置元素以渲染遊戲對象。
- 1. 什麼運營商應該宣佈爲朋友?
- 2. 爲什麼以下函數可以在不聲明爲朋友或成員函數的情況下訪問類成員?
- 3. 不能宣佈的朋友的typedef
- 4. 一個非成員函數如何實現一個類的朋友函數呢?
- 5. 將非會員非朋友函數加入到成員函數
- 6. 爲什麼朋友成員函數不能自動識別爲函數模板?
- 7. 從朋友函數內的對象訪問成員函數
- 8. Effective C++項目23首選成員函數的非成員非朋友函數
- 9. 防止朋友函數訪問某個類的私有成員
- 10. 從成員函數轉換爲朋友函數
- 11. 運算符==是成員函數還是朋友函數?
- 12. 成員是從朋友類
- 13. 在這種情況下應該是什麼數據類型?
- 14. 在什麼情況下,表單方法應該是GET,它應該是什麼情況POST
- 15. 一個類的朋友函數
- 16. 聲明前向聲明的類的成員函數爲朋友
- 17. 沒有類聲明的朋友成員函數
- 18. 在什麼情況下,超類不應該是抽象的?
- 19. 類在這種情況下不可用,因爲它是朋友
- 20. 默認情況下是虛擬的成員函數嗎?
- 21. 運算符重載(朋友和成員函數)
- 22. 在什麼情況下,該應用程序:didFinishLaunchingWithOptions:被調用?
- 23. 在什麼情況下應該避免單元測試?
- 24. OpenLayers:在什麼情況下我應該銷燬地圖
- 25. 我應該在什麼情況下使用模塊和課程
- 26. 在什麼情況下REST API應該返回HTTP狀態503
- 27. 在什麼情況下我們應該選擇maven?
- 28. 巴什 - 如何調用一個函數,在這種情況下
- 29. 如何獲取用戶朋友中的每一個朋友的朋友數?
- 30. 在不清除整個畫布的情況下替換函數?
+1爲「不違反」。但是,對於複雜,理性等大多數數字類來說,它是無用的。 – 2009-12-07 10:15:30