运算符重载函数作为类成员函数和友元函数

作为类成员函数的例子:
#include <iostream> using namespace std; class Complex{ public: Complex(){real = 0; imag = 0;} Complex(double r, double i){real = r; imag = i;} Complex operator +(Complex& c2);//看似只有一个参数,实际上有两个参数,由于重载函数是类的成员函数,有一个参数是隐含的,运算符函数 void display(); //是用this指针隐式地访问类对象的成员。 private: double real; double imag; }; Complex Complex::operator+(Complex& c2){ return Complex(real+c2.real, imag+c2.imag); } void Complex::display(){ cout<<"("<<real; if (imag>0){cout<<"+";} cout<<imag<<"i)"<<endl; } int main(){ Complex c1(3,4), c2(5,-10), c3; c3 = c1 + c2; cout<<"c1=";c1.display(); cout<<"c2=";c2.display(); cout<<"c3=";c3.display(); return 0; }

作为类的友元函数的例子:

#include <iostream>
using namespace std;

class Complex{
public:
	Complex(){real = 0; imag = 0;}
	Complex(double r, double i){real = r; imag = i;}
	friend Complex operator +(Complex& c1, Complex& c2);
	void display();

private:
	double real;
	double imag;
};

Complex operator+(Complex& c1, Complex& c2){
	return Complex(c1.real+c2.real, c1.imag+c2.imag);
}

void Complex::display(){
	cout<<"("<<real;
	if (imag>0){cout<<"+";}
	cout<<imag<<"i)"<<endl;
}

int main(){
	Complex c1(3,4), c2(5,-10), c3;
	c3 = c1 + c2;//将被解释成:c3 = operator+(c1, c2);
	cout<<"c1=";c1.display();
	cout<<"c2=";c2.display();
	cout<<"c3=";c3.display();
	return 0;
}

运算符重载函数有3种情况:普通函数、类的成员函数、类的友元函数
1.在极少数的情况下才会使用普通函数,因为普通函数不能直接访问类的私有成员。解决方法是在类中定义公用的设置数据的set函数和读取数据的get函数,在重载函数中调用这些函数去访问类的私有成员。显然这样不好。

2.如果将运算符重载函数作为成员函数,它可以通过this指针自由地访问本类的数据成员,因此可以少写一个函数的参数。但必须要求运算表达式的第一个参数是一个类对象,而且与运算符函数类型相同。

3.如果运算符左侧的操本作数不是本类对象,则运算符重载函数不能作为成员函数,只能作为非成员函数;如果函数需要访问类的私有成员,则必须声明为该类的友元函数。

4.将双目运算符重载为友元函数是,在函数的形参列表必须有两个参数,不能省略,形参的顺序任意,不要求第一个参数必须为类对象。但在使用运算符的表达式中,要求运算符左侧的操作数与函数的第一个参数对应,运算符右侧的操作数与函数的第二个参数对应。数学上的交换律在此不适用。解决方法是再重载一次,交换参数顺序。

5.由于友元会破坏类的封装,因此原则上,要尽量将运算符函数作为成员函数。但考虑到各方面的因素,一般将单目运算符重载为成员函数,将双目运算符重载为友元函数。
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页