【本文部分内容来自网络】
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/