大多数情况下,成员函数重载和友元函数重载效果并无差别。例如这里我们以复数的加法为例:
#include<iostream>
using namespace std;
using namespace std;
class Complex
{
public:
Complex():real_(0),imag_(0){}
Complex(int real,int imag):real_(real),imag_(imag){}
{
public:
Complex():real_(0),imag_(0){}
Complex(int real,int imag):real_(real),imag_(imag){}
//成员函数重载
Complex operator+(const Complex& addThis)
{
int real = real_ + addThis.real_;
int imag = imag_ + addThis.imag_;
Complex tmp(real, imag);
return tmp;
}
Complex operator+(const Complex& addThis)
{
int real = real_ + addThis.real_;
int imag = imag_ + addThis.imag_;
Complex tmp(real, imag);
return tmp;
}
//友元函数重载
friend Complex operator+(const Complex& c1, const Complex& c2)
{
int real = c1.real_ + c2.real_;
int imag = c1.imag_ + c2.imag_;
Complex tmp(real, imag);
return tmp;
}
friend Complex operator+(const Complex& c1, const Complex& c2)
{
int real = c1.real_ + c2.real_;
int imag = c1.imag_ + c2.imag_;
Complex tmp(real, imag);
return tmp;
}
void Display()
{
if (imag_ >= 0)
cout << real_ << '+' << imag_ << 'i' << endl;
else
cout << real_ << imag_ << 'i' << endl;
}
private:
int real_;
int imag_;
};
{
if (imag_ >= 0)
cout << real_ << '+' << imag_ << 'i' << endl;
else
cout << real_ << imag_ << 'i' << endl;
}
private:
int real_;
int imag_;
};
int main(void)
{
Complex c1; //real_=0,imag_=0
Complex c2(10, 10);
c1.Display();
c2.Display();
cout << endl;
cout << "c1+c2=";
Complex c3 = c1 + c2;
c3.Display();
}
{
Complex c1; //real_=0,imag_=0
Complex c2(10, 10);
c1.Display();
c2.Display();
cout << endl;
cout << "c1+c2=";
Complex c3 = c1 + c2;
c3.Display();
}
下面说一种特殊情况,关于存在隐式转换的类的双目运算符的重载,这里举一个简单的例子,弄懂原理即可
先用成员函数重载+:
#include<iostream>
using namespace std;
using namespace std;
class Int
{
public:
Int(int i = 0);
//成员函数重载+
Int operator+(const Int& addThis)
{
Int tmp(i_+addThis.i_);
return tmp;
}
void Display()
{
cout << i_ << endl;
}
private:
int i_;
};
{
public:
Int(int i = 0);
//成员函数重载+
Int operator+(const Int& addThis)
{
Int tmp(i_+addThis.i_);
return tmp;
}
void Display()
{
cout << i_ << endl;
}
private:
int i_;
};
Int::Int(int i):i_(i) //注意!!只带一个参数的构造函数存在隐式转换
{}
{}
int main(void)
{
Int i1(10);
Int i2 = i1 + 9; //正常运行,这里存在一个隐式转换,
//把int类型的9转换成类类型Int
//相当于i2=i1.operator+(9)
i1.Display();
i2.Display();
{
Int i1(10);
Int i2 = i1 + 9; //正常运行,这里存在一个隐式转换,
//把int类型的9转换成类类型Int
//相当于i2=i1.operator+(9)
i1.Display();
i2.Display();
Int i3 = 9 + i2; //无法运行,因为i3=9.operator+(i2),这里的9并不是类类型Int
}
}
再用友元函数重载:
#include<iostream>
using namespace std;
using namespace std;
class Int
{
public:
Int(int i = 0);
{
public:
Int(int i = 0);
//友元函数重载
friend Int operator+(const Int& i1, const Int& i2)
{
Int tmp(i1.i_ + i2.i_);
return tmp;
}
void Display()
{
cout << i_ << endl;
}
private:
int i_;
};
friend Int operator+(const Int& i1, const Int& i2)
{
Int tmp(i1.i_ + i2.i_);
return tmp;
}
void Display()
{
cout << i_ << endl;
}
private:
int i_;
};
Int::Int(int i):i_(i) //注意!!只带一个参数的构造函数存在隐式转换
{}
{}
int main(void)
{
Int i1(10);
Int i2 = 9 + i1; //正常运行,这里也发生了隐式转换
//i2=operator+(9,i1);两个参数都是类类型Int,
//所以对int型9发生了隐式转换
i2.Display();
}
{
Int i1(10);
Int i2 = 9 + i1; //正常运行,这里也发生了隐式转换
//i2=operator+(9,i1);两个参数都是类类型Int,
//所以对int型9发生了隐式转换
i2.Display();
}
所以,一般情况下,最好对双目运算符用友元函数重载!!
以下几种双目运算符不能以友元函数重载:
“=”、“()”、"[]"、“->”
而流运算符只能以友元函数的方式重载。