运算符重载的规则如下:
1) C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已经有的运算符
2) 重载之后运算符的优先级和结合性都不会改变
3) 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造,一般来说,重载的功能应当与原有功能相似,不能改变原运算符的操作对象个数,同时至少有一个操作对象是自定义类型。
不能重载的运算符个数有五个,类属关系运算符‘.’、成员指针运算符‘.*’、作用域分辨符‘::’、sizeof运算符和三目运算符‘?:’
运算符的重载形式有两种,重载为类的成员函数和重载为类的友元函数
运算符重载为类的成员函数的一般语法形式:
函数类型 operator 运算符(形参表)
{
函数体;
}
运算符重载为友元函数,可以在类中声明友元函数的原型,在类外实现,也可以在类体中写成如下的内联形式:
friend函数类型 operator 运算符(形参表)
{
函数体;
}
1) 函数类型指明了重载运算符的返回值类型,也就是运算结果类型,operator是定义运算符重载函数的关键字,运算符是要重载的运算符名称,必须是C++中可重载的运算符,比如“+、-”
2) 当运算符重载为类的成员函数时,函数的参数个数比原来的操作数个数要少一个(后置++、--除外);当重载为类的友元函数时,参数个数与原操作数个数相同。
重载为类的成员函数:
关于等价性:
对于双目运算符B,表达式oprd1 B oprd2(oprd1为A类的对象),经过重载之后,oprd1 B oprd2
就相当于函数调用oprd1.operator B(oprd2)
关于单目运算符U 如“-”,U oprd相当于函数调用oprd.operator U()
后置运算符如“++”和“--”,如实现oprd++或oprd--,其中oprd为A类的对象,其中oprd为A类的对象,那么运算符就应当重载为A类的成员函数,这时函数要带有一个整形(int)形参.重载之后,表达式oprd++和oprd—就相当于oprd.operator ++(0),oprd.operator—(0).这里的int类型参数在运算中不起任何作用,只是用于区别后置++、--与前置++、--.
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstdlib>
class complex{
public:
complex(double r = 0.0,double i = 0.0){real = r;imag = i;}
complex operator + (complex c2);
complex operator - (complex c1);
void display();
private:
double real;
double imag;
};
complex complex::operator + (complex c2){
return complex(real+c2.real,imag+c2.imag);
}
complex complex::operator- (complex c2){
return complex(real-c2.real,imag-c2.imag);
}
void complex::display(){
cout << "(" << real << "," << imag << ")" << endl;
}
int main(){
complex c1(5,4),c2(2,10),c3;
cout << "c1=";
c1.display();
cout << "c2=";
c2.display();
// c3 = c1 - c2;
c3 = c1.operator-(c2);
cout << "c3 = c1 - c2 =";
c3.display();
// c3 = c1 + c2;
c3 = c1.operator+(c2);
cout << "c3 = c1 + c2 =";
c3.display();
system("pause");
}
#include <iostream>
using namespace std;
class Clock{
public:
Clock(int NewH = 0, int NewM = 0, int NewS = 0);
void ShowTime();
Clock& operator++();
Clock operator++(int);
private:
int Hour,Minute,Second;
};
Clock::Clock(int NewH,int NewM,int NewS){
if(0 <= NewH && NewH < 24 && 0 <= NewM && NewM < 60 && 0 <= NewS && NewS < 60){
Hour = NewH;
Minute = NewM;
Second = NewS;
}else{
cout << "Time error !" << endl;
}
}
void Clock :: ShowTime(){
cout << Hour << ":" << Minute << ":" << Second << endl;
}
Clock& Clock::operator++(){
Second++;
if(Second >= 60){
Minute++;
Second -= 60;
if(Minute >= 60){
Hour ++;
Minute -= 60;
Hour %= 24;
}
}
// cout << Hour << "x" << Minute << "x" << Second << endl;
return (*this);
}
Clock Clock::operator++(int){
Clock old = *this;
++(*this);
return old;
}
int main(){
Clock myClock(23,59,59);
cout << "First time output:";
myClock.ShowTime();
cout << "Show myClock ++:";
//(myClock++).ShowTime();
(myClock.operator++(0)).ShowTime();
cout << "Show ++ myClock:";
(++myClock).ShowTime();
//(myClock.operator++()).ShowTime();
system("pause");
}
重载为类的友元函数:
关于等价性:
关于双目运算符B,如果它的一个操作数为A类的对象,就可以将B重载为A类的友元函数,该函数有两个形参,其中一个形参的类型是A类,表达式oprd1 B oprd2 相当于函数调用operator B(oprd1,oprd2)
对于单目运算符U,如-(负号),如果要实现U oprd,其中oprd为A类的对象,则U可以重载为A类的友元函数,函数的形式参数是A类的对象oprd,U oprd相当于函数调用operator U(oprd)
对于后置运算符++和--,oprd++和oprd--,就相当于函数调用operator ++(oprd,0)以及
operator --(oprd,0),第一个形参是A类的操作对象,第二个用于区分前置运算符.
#include <iostream>
using namespace std;
class complex{
public:
complex(double r=0.0,double i=0.0){real = r;imag = i;}
friend complex operator+(complex c1, complex c2);
friend complex operator-(complex c1, complex c2);
/// ÔËËã·û-ÖØÔØÓÑÔªº¯Êý
void display();
private:
double real;
double imag;
};
void complex::display(){
cout << "(" << real << "," << imag << ")" << endl;
}
complex operator + (complex c1,complex c2){
return complex(c1.real+c2.real,c1.imag+c2.imag);
}
complex operator - (complex c1, complex c2){
return complex(c1.real-c2.real,c1.imag-c2.imag);
}
int main(){
complex c1(5,4),c2(2,10),c3;
cout << "c1=";
c1.display();
cout << "c2=";
c2.display();
//c3 = c1 - c2;
c3 = operator-(c1,c2);
cout << "c3=c1-c2=";
c3.display();
//c3 = c1 + c2;
c3 = operator+(c1,c2);
cout << "c3=c1+c2=";
c3.display();
system("pause");
}