none
关于友元函数的问题? RRS feed

  • 问题

  •  class Author
    {
    public:
        Author()
        {
        }
    private:
       
    char *name;
        list
    <Book> books;
        ostream
    & printAuthor(ostream&) const;
        friend ostream
    & operator <<(ostream& out,const Author& ar)//1
        {
           
    return ar.printAuthor(out);
        }
    };
    template
    <class T>//2
    ostream& operator<< (ostream& out,const list<T>& lst)
    {
       
    for(list<T>::const_iterator ref = lst.begin();ref!=lst.end();ref++)
           
    out<<*ref;//overloaded <<
        return out;
    }

    上边重载 < <的函数是成员函数还是友元函数啊,如果是友元函数的话,在类里声明友元函数就行了,怎么还定义了友元函数?如何解释1和2之间的关系?以前没见过这种形式,望给详细解释一下  先谢谢了
    2009年2月14日 14:35

答案

  • 你好,这里operator必须是非成员函数。这和操作符重载的调用有关。声明为成员变量的操作符重载是后置操作符。
    举个例子,如果我们在类A中重载a& operator+(int n);,并把他写为成员变量。
    那么只能在调用的时候写成
    A a;
    A b;
    a = b + 1;//这里的operator +前面必须是一个A类型,也就是说运算符是后置的。
    如果写成
    a = 1 + b;
    这样就会报错。编译器会抱怨你没有声明一个前置的运算符重载。
    于是就需要声明一个非成员函数的运算符重载。这个函数的要声明在类的外部。那么,由于在operator重载中往往会访问类中的私有成员变量,就需要把这个非成员函数定义为有元。并且有时,这个非成员函数需要和类的声明一起出现。就需要非成员函数为inline。
    那么这是
    a = 1+ b就可以顺利地通过编译。
    对于你这个标准io操作。不把operator<<定义为非成员函数。
    cout<<1<<b<<endl;
    如果如上述方式调用,是无法通过编译的。
    所以一定要把operator<<和operator>>的io操作定义为非成员函数。并且最好此时不要在你的类中声明隐式数值转换操作符。否则有些情况下,编译器会认为operator<<或operator>>是一个位移操作。

    这里还要再提一下,刚才虽然把operator<<作为非成员函数,但是此时operator<<也是类A的一部分。Koeing查找规则说明了这一点。关于这个问题请仔细阅读Exceptional C++.
    2009年2月15日 3:39
    版主

全部回复

  • 你好,这里operator必须是非成员函数。这和操作符重载的调用有关。声明为成员变量的操作符重载是后置操作符。
    举个例子,如果我们在类A中重载a& operator+(int n);,并把他写为成员变量。
    那么只能在调用的时候写成
    A a;
    A b;
    a = b + 1;//这里的operator +前面必须是一个A类型,也就是说运算符是后置的。
    如果写成
    a = 1 + b;
    这样就会报错。编译器会抱怨你没有声明一个前置的运算符重载。
    于是就需要声明一个非成员函数的运算符重载。这个函数的要声明在类的外部。那么,由于在operator重载中往往会访问类中的私有成员变量,就需要把这个非成员函数定义为有元。并且有时,这个非成员函数需要和类的声明一起出现。就需要非成员函数为inline。
    那么这是
    a = 1+ b就可以顺利地通过编译。
    对于你这个标准io操作。不把operator<<定义为非成员函数。
    cout<<1<<b<<endl;
    如果如上述方式调用,是无法通过编译的。
    所以一定要把operator<<和operator>>的io操作定义为非成员函数。并且最好此时不要在你的类中声明隐式数值转换操作符。否则有些情况下,编译器会认为operator<<或operator>>是一个位移操作。

    这里还要再提一下,刚才虽然把operator<<作为非成员函数,但是此时operator<<也是类A的一部分。Koeing查找规则说明了这一点。关于这个问题请仔细阅读Exceptional C++.
    2009年2月15日 3:39
    版主
  • 第一种也是全局函数,你可以在类里实现友元函数,但是它并不是类的成员函数

    具体参见C++标准
    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
    My MSDN Blog: http://blogs.msdn.com/xiangfan
    2009年2月17日 14:19