C++標準:
3. A function first declared in a friend declaration has
external linkage (3.5). Otherwise, the function retains its previous linkage (7.1.1).
按照
3中說的,下面代碼是應該通過的
class?X
{
????friend?void?f();?
};
int?main()
{
????f();?//因為類X中的友元函數f的聲明有外部鏈接,所以,f可見
}
void?f()?{?/*?ok?to?define?friend?function?in?the?class?body?*/?}
編譯測試:
VC2005/2010通過 ,而GCC 4.4.3報錯:無法找到名字f
5. A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8),the function name is unqualified, and the function has namespace scope.
[Example:
class M {
? ? friend void f() { } //
definition of global f, a friend of M,
? ? ? ? ? ? ? ? ? ? ? ? // not the definition of a member function
};
—end example]
Such a function is implicitly inline. A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).
按照
5中說的,既然在類中定義友元函數f,是"definition of global f",那么也就可以理解為下面的代碼是可以通過編譯的
class?X
{
????friend?void?f(){?/*?ok?to?define?friend?function?in?the?class?body?*/?}
};
int?main()
{
????f();?
}?
然而VC2005/2010和GCC4.4.3都不能通過
TCPL中對友元有如下說明:
? “一個友元聲明不會給外圍的作用域引進一個名字”?
? “一個友元函數或者需要在某個外圍作用域里顯式聲明,或者以它的類或由該類派生的類作為一個參數(13.6節),否則就無法調用這個友元了。”
C++ primer有如下:
? “友元聲明將已命名的類或非成員函數引入到外圍作用域中。此外,友元函數可以在類的內部定義,該函數的作用域擴展到包圍該類定義的作用域。”?
? “用友元引入的類名和函數(定義或聲明),可以像預先聲明的一樣使用”
C++ primer中的例子:
class X {
? ? ? ? friend class Y;
? ? ? ? friend void f() { /* ok to define friend function in the class body */ }
};
class Z {
? ? ? ? Y *ymem; // ok: declaration for class Y introduced by friend in X
? ? ? ? void g() { return ::f(); } // ok: declaration of f introduced by X
};
標準中說的和C++ PRIMER一樣,而和TCPL不一樣。
至于編譯器,GCC做的和TCPL說的一樣,而VC和標準說的部分一樣(對于在友元聲明出定義函數處有出入)
個人總結
兩個編譯器行為不同,所以盡量提前聲明友元所聲明的名字
以上只是個人的看法,如果有不對的地方,
懇請各位大大指正
posted on 2010-03-07 10:49
zhaoyg 閱讀(486)
評論(0) 編輯 收藏 引用 所屬分類:
C/C++學習筆記