2010-05-05 49 views

回答

12

Jacob是正確的...一個friend在一個類中聲明的函數可以訪問那個類,但它根本不在類內部,其他人都可以訪問它。

對於不屬於該類的成員的運算符重載(也稱爲自由函數,它可能是朋友,也可能不是),參數與操作數相同。對於類的成員之一,第一個操作數是「隱式參數」,它變爲this

隱式參數是從所述第一個參數的自由功能在幾個方面不同:

  • 它的類型是參考與班級,而自由功能可以聲明的任何類型的用於它的第一個參數。
  • 它不參與隱式類型轉換。 (它不會被轉換構造函數臨時初始化。)
  • 它參與虛擬重寫解析。 (A virtual超載將由動態型的第一操作數,這是不可能的而無需額外的代碼的分類功能中選擇。)

的情況是爲一元,二元,或n進制相同的(在operator()的情況)。

成員突變的特權:運營商改變其第一個操作數(例如+==,前綴++)應該被實現爲成員函數,並應完全實現所有重載的膽量。 Postfix ++是二等公民;它被實施爲Obj ret = *this; ++ this; return ret;。請注意,這有時會擴展到可能包含*this = initializer的複製構造函數。

乘客自由規則:只有交換運營商(如/)應該是免費功能;所有其他運營商(例如一元公司)都應該成爲會員。交換運營商固有地製作了對象的副本;它們實現爲Obj ret = lhs; ret @= rhs; return ret;,其中@是交換運算符,lhsrhs分別是左側和右側參數。

C++友情黃金規則:避免友誼。 friend污染設計的語義。 超載推論:如果遵循上述規則,超載很簡單,那麼friend是無害的。樣板過載定義允許它們放置在支架內。

注意,一些運營商也不能隨意功能:=->[](),因爲標準具體是這麼說的第13.5。我認爲就是這樣......我認爲一元&*也是,但我顯然是錯的。他們應該總是作爲成員超載,但只有經過仔細考慮!

+0

爲什麼一元運營商不能成爲朋友? – Vijay 2010-05-05 05:21:32

+2

因爲他們沒有必要。 Friend運算符允許您在二元運算符的右側放置類類型。由於一元操作員沒有右側,所以你不需要他們成爲朋友。 – Stewart 2010-05-05 05:36:38

+0

@cpp:對不起,我誤記了標準。沒關係。 – Potatoswatter 2010-05-05 05:38:12

3

區別在於友誼函數實際上在全局範圍內,因此您不需要成爲該類的實例即可訪問它。

1

成員函數要求左手操作符必須是該類型的。 朋友函數可以允許在左邊的操作符上進行隱式轉換。

例如,讓我們說我們創建一個BigInt類。我們創建一個成員函數操作符+來獲取BigInt的右手操作符。

現在讓我們也說BigInt有一個構造函數,它需要一個常規的int。這個構造函數不是顯式的(顯式關鍵字),它需要一個參數。這意味着C++可以從int轉換爲BigInt。

當我們有這些東西,我們可以這樣做:

BigInt有富(5); BigInt酒吧; bar = foo + 5;

但是,我們不能做到這一點:

BigInt有富(5) BigInt有條; bar = 5 + foo;

但是,如果我們使用了朋友函數而不是成員函數,那麼兩者都可以工作。

0

可以在rvalues上調用成員函數,而接受對非const的引用的自由函數不能用rvalues調用。例如,如果您實施operator++作爲成員,則僅編譯++function_returning_iterator_by_value()

1

成員函數要求左側操作符必須是該類型的。朋友函數可以允許在左邊的操作符上進行隱式轉換。

相關問題