2012-10-18 67 views
1

這裏是類是否需要在朋友函數中使用訪問器?

class Instructor 
{ 
public: 

Instructor (int id , string name) ;// constructor 
~Instructor()      ; 

// methods 
string    getName   () ; 
int     getID   () ; 



private: 

int     id    ; 
string    name   ; 

friend ostream & operator<< (ostream & out , Instructor & instructor) ; 
} ; 

這裏是ostream的功能

ostream & operator<< (ostream & out , Instructor & instructor) 
{ 
out << "ID:" << instructor.getID() << "\t NAME:" << instructor.getName() << "\t OFFERED_COURSES:" ; 


return out << endl ; 

}

而這裏的getName和的getID方法

string Instructor::getName() 
{ 
    return this->name ; 
} 


int Instructor::getID() 
{ 
    return this->id ; 
} 

,我的問題是,爲什麼我們是否需要使用getID和getname函數?我們不能通過寫「this-> name」來訪問名字嗎?感謝您的回答。

+0

誰說我們不可以? –

+1

我擔心這個問題可能會變成關於風格問題的燃燒式戰爭我認爲朋友的行爲 – CashCow

回答

4

必要否,建議是。事實上,根本沒有必要聲明friend,這是更加封裝的。

+0

爲什麼推薦? – user1559792

+3

@ user1559792,以便您可以更改影響最小代碼的實現。 –

+0

那麼你可以說成員函數也應該使用訪問器,所以如果你改變了類的表示形式,你不必改變它們。 朋友應該被視爲類成員。 – CashCow

3

這可能不是「不應該」,「不應該」。此時,getID()只是返回底層變量,但不能保證它不會更改爲不同的表示形式。尊重封裝,當你遇到它。

0

你可以做到這一點(直接訪問私人成員的朋友功能),但它不是最好的辦法。使用檢查器的功能,因爲它們應該被寫入,以暴露類的私有狀態,以寫入該類的方式使它們在外部使用這個實際的私人領域可以用來做內部需要做的事情

因爲您在操作員功能中沒有使用私人成員,所以您甚至不需要它成爲朋友。

+0

我不同意,朋友是實施的一部分,就像班級成員一樣。 – CashCow

+0

我反對不同意:)。如果朋友真的與班級的實施相關聯,那麼這將是班上誠實的成員。 – Omaha

+0

與流不能。您當然可以提供您的流程調用的成員「打印」功能(當打印需要私人訪問時)。 對於擁有不同生命週期的類,您可以使用嵌套類,但是您可能會說您從不需要朋友。 – CashCow

0

不,朋友真的是你班級實施的延伸部分,因此可以直接訪問它。

如果您已將函數或類聲明爲不是其實現細節的一部分的朋友,那可能是對朋友的不當使用。

就你而言,你可以完全移除流媒體朋友的重載,但是如果你決定你的課程同樣支持流式傳輸,並且不想支持setter函數(或交換),你將會唯一剩下的選擇是將您的流作爲朋友直接寫入成員變量。

(注意,流式,如果失敗的話,應該把該對象在默認(新建)狀態。

流出來應該是一個朋友的時候(最好只有當)它需要寫給你一般不會提供直接訪問的流成員

+0

「流入,如果失敗,應該將對象留在默認(新構造)狀態」 - 爲什麼那麼呢?爲什麼不是有效但未明確的?與之前開始時相同的效果會更好,但不一定高效。有一個特殊的問題,如果在流上設置了相關的標誌,它可能會在發生異常時拋出異常 - 按照您的說法執行要求捕獲異常,清除對象然後重新拋出。或者首先清理對象,然後執行與流入操作相同的失敗前版本。 –

+0

@SteveJessop我記得在C++ 11中讀到int i = 5; ISTR >>我;和流失敗,我現在應該是0.我也很驚訝,但如果這是新標準,應該嘗試堅持下去。我原以爲國家也應該「不變」。 – CashCow

+0

嗯。 'std :: string'有一個提取器,它在開始之前擦除字符串。在22.4.8/9中有一些示例代碼會在用戶定義的「Date」未修改時保留原樣,但這是使用語言環境的示例,不一定是提取器最佳實踐的示例。就像你說的那樣,算術提取器在失敗時似乎存儲零(22.4.2.1.2/3)。它看起來好像一個「行爲良好」的提取器不應該使用其他流提取器,而應該使用locale「get」函數並在流中設置錯誤(可能拋出異常)。 –