随笔-59  评论-36  文章-0  trackbacks-0
C++标准:

3. A function first declared in a friend declaration hasexternal 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 阅读(464) 评论(0)  编辑 收藏 引用 所属分类: C/C++学习笔记

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理