C/C++重载运算符

所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新功能。运算符也可以重载运算符重载是对已有的运算符赋予多重含义

必要性
C++中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类)
(一) C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。


(二) C++允许重载的运算符C++中绝大部分的运算符允许重载.不能重载的运算符只有5个:
(1) 成员访问运算符.
(2) 作用域运算符∷
(3) 条件运算符?:
(4) 成员指针运算符*
(5) 编译预处理命令的开始符号#


(三) 重载不能改变运算符运算对象(即操作数)的个数。


(四) 重载不能改变运算符的优先级别。


(五) 重载运算符的函数不能有默认的参数,否则就改变了运算符参数的个数,与前面第(3)点矛盾。


(六) 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。也就是说,参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。


(七) 用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载。
① 赋值运算符(=)可以用于每一个类对象,可以利用它在同类对象之间相互赋值。
② 地址运算符&也不必重载,它能返回类对象在内存中的起始地址。


总之,当C++语言原有的一个运算符被重载之后,它原先所具有的语义并没有消失,只相当于针对一个特定的类定义了一个新的运算符。


运算符重载可以使用成员函数和友元函数两种形式。可以参考以下的经验:
(1)只能使用成员函数重载的运算符有:=、()、[]、->、new、delete。
(2)单目运算符最好重载为成员函数。
(3) 对于复合的赋值运算符如+=、-=、*=、/=、&=、!=、~=、%=、>>=、<<=建议重载为成员函数。
(4) 对于其它运算符,建议重载为友元函数。


运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的运算符重载实质上是函数的重载。


重载运算符的函数一般格式如下: 

函数类型 operator 运算符名称 (形参表列)
{
对运算符的重载处理
}


重载为类成员函数时参数个数=原操作数个数-1
(后置++、--除外)
重载为友元函数时 参数个数=原操作数个数,且至少应该有一个自定义类型的形参。
将“+”、“-”运算重载为复数类的成员函数。
规则:
实部和虚部分别相加减。
操作数:
两个操作数都是复数类的对象。

#include "StdAfx.h"
#include<iostream>

using namespace std;

class complex //复数类声明
{
public: //外部接口
	complex(double r=0.0,double i=0.0)
	{
		real=r; 
		imag=i;
	} //构造函数
	complex operator + (complex c2); //+重载为成员函数
	complex operator - (complex c2); //-重载为成员函数
	void display(); //输出显示复数
private: //私有数据成员
	double real; //复数实部
	double imag; //复数虚部
};
complex complex::operator +(complex c2) //重载函数实现
{
	complex c;
	c.real=real+c2.real;
	c.imag=imag+c2.imag;
	return complex(c.real,c.imag);
}
complex complex::operator -(complex c2) //重载函数实现
{
	complex c;
	c.real=real-c2.real;
	c.imag=imag-c2.imag;
	return complex(c.real,c.imag);
}
void complex::display()
{ 
		cout<<"("<<real<<","<<imag<<"i"<<")"<<endl; 
}

void main() //主函数
{ 
	complex c1(5,4),c2(2,10),c3; //声明复数类的对象
	cout<<"c1="; c1.display();
	cout<<"c2="; c2.display();

	c3=c1-c2; //使用重载运算符完成复数减法
	cout<<"c3=c1-c2=";c3.display();

	c3=c1+c2; //使用重载运算符完成复数加法
	cout<<"c3=c1+c2=";c3.display();

	system("pause");
}

程序输出的结果为:

c1=(5,4i)
c2=(2,10i)
c3=c1-c2=(3,-6i)
c3=c1+c2=(7,14i)


在本程序中对运算符“+”,”-”进行了重载,使之能用于两个复数的相加减在该例中运算符重载函数operator+ ,operator-作为Complex类中的成员函数


“+” ,”-”是双目运算符,为什么在程序中的重载函数中只有一个参数呢?

实际上,运算符重载函数有两个参数,由于重载函数是Complex类中的成员函数,有一个参数是隐含的,运算符函数是用this指针隐式地访问类对象的成员。
可以看到,重载函数operator+访问了两个对象中的成员,一个是this指针指向的对象中的成员,一个是形参对象中的成员。如this->real+c2.real,this->real就是c1.real。
在将运算符函数重载为成员函数后,如果出现含该运算符的表达式,如c1+c2,编译系统把它解释为c1.operator+(c2)
即通过对象c1调用运算符重载函数,并以表达式中第二个参数(运算符右侧的类对象c2)作为函数实参。运算符重载函数的返回值是Complex类型,返回值是复数c1和c2之和(Complex(c1.real + c2.real,c1.imag+c2.imag))。

最后再罗列一个简单的运算符重载的例子:

#include "StdAfx.h"
#include <iostream>
using namespace std;

class Lyhdian
{
	double X;
	double Y;
public:
	Lyhdian(double,double);
	Lyhdian operator +(Lyhdian& a1);
	Lyhdian operator -(Lyhdian& a1);
	void show();
};

Lyhdian::Lyhdian(double a,double b)//构造函数
{
	X=a;
	Y=b;
}
Lyhdian Lyhdian::operator +(Lyhdian& a1)
{
	double c=X+a1.X;
	double d=Y+a1.Y;
	Lyhdian result(c,d);
	return result;
}
Lyhdian Lyhdian::operator -(Lyhdian& a1)
{
	double c=X-a1.X;
	double d=Y-a1.Y;
	Lyhdian result(c,d);
	return result;
}
void Lyhdian::show()
{
	cout<<"点的坐标为:"<<endl;
	cout<<"("<<X<<","<<Y<<")"<<endl;
}
void main()
{
	double X;
	double Y;
	Lyhdian cc(0,0);
	cout<<"请输入一点的坐标:"<<endl;
	cin>>X>>Y;
	Lyhdian aa(X,Y);
	cout<<"请输入另一点的坐标:"<<endl;
	cin>>X>>Y;
	Lyhdian bb(X,Y);
	cout<<"两点进行加运算:"<<endl;
	cc=aa+bb;
	cc.show();
	cout<<"两点进行减运算:"<<endl;
	cc=aa-bb;
	cc.show();
	system("pause");
}


你可能感兴趣的:(C/C++重载运算符)