友元与重载

【本文部分内容来自网络】

    1.对双目运算符而言,成员函数重载运算符的函数参数表中只有一个参数,而用友元函数重载运算符函数参数表中有两个参数对单运算符来说,成员函数重载运算符的函数参数表中没有参数,而用友元函数重载运算符函数参数表中含有一个函数。这个问题要搞清楚,有一个this指针的问题。。。

    2.双目运算符一般可以用友元函数重载和成员函数重载,但有一种情况只可以用友元函数重载,就是:双目运算符左边的变量是一个常量,而不是对象!!!也就是说 :=赋值运算符,()函数调用运算符,[]下标运算符,->通过指针访问成员的运算符能通过成员函数重载。

接下来解释一下为什么这四个运算符不能通过友元重载

先看一段测试程序:

#include <iostream>

using namespace std;

class A

{

private:

    int x;

public:

    A(){x = 10;}

    A(int y)

    {

        cout << cout<<"Call A(int xx)"<<endl;

        x = y;

    }

    A operator=(int xx)   //重载赋值运算符运算
     {

            cout<<"Call A operator=(int xx)"<<endl;

           x = xx;
            return *this;
      }

};

int main (void)

{

    A a;

    a =5;

return 0;

}

程序运行结果:
Call A operator=(int xx)


在此,我们可以对C++规则做出以下的判断:
 当类中没有定义赋值运算符重载成员函数时(注意,在未定义形参数据类型为该类类型的赋值运算符重载函数时,编译器会自动生成加入),当程序执行到某一赋值语句时,程序就会调用与赋值语句中右值类型匹配的构造函数,而把这右值当作此构造函数的实参。像最初的赋值语句a =5,执行时,实际做的操作是a(5)。而当类中有定义赋值运算符重载成员函数,执行赋值语句时,程序就只会去调用相应的赋值运算符重载函数。


 我们知道友元函数不是类的成员函数,它只是具有访问声明的类的数据成员的权限而已。

那么当把赋值运算符重载为类的友员函数,在程序中执行类对象的赋值语句时,程序就会出现两种矛盾的选择。
1、因为类中并没有重载赋值运算符的成员函数,所以它根据C++的规则,会去调用相应的构造函数。
2、但是在全局里,我们已经重载了参数类型为此类类型的赋值运算符函数,而这赋值语句刚好和这函数匹配上了,根据C++的规则,也会去调用这函数。

同理,()函数调用运算符,[]下标运算符,->通过指针访问成员的运算符,也是一样。


如下声明:

A operator+(const A &t) const;

可以以同样意思的原型

friend Aoperator+(const A &t1, const A &t2);

这里,对于成员函数重载来说,一个操作数通过this指针隐式传递,另一个操作数做为参数传递;对于友元版本来说,两个操作数都做为参数传递。

然而在函数定义时,只能选择其中一种格式,原因同上面分析的一样,两种格式都与同一个表达式匹配会造成二义性错误


版权声明:本文原创,转载请注明来自 http://kymjs.com/

你可能感兴趣的:(友元与重载)