重载运算符
一
重载的目的:使用户的数据以自定义的方式进行工作。
要求:重载运算符函数可以对运算符作出新的解释,但原有基本语义不变:重载后有多个意思
不改变运算符的优先级
不改变运算符的结合性
不改变运算符所需要的操作数
不能创建新的运算符
不能重载的运算符:. :: .* ?: sizeof
运算符重载的两种方法:①将运算符函数重载为成员函数
②将运算符函数重载为友元函数
重载格式:
函数类型 operator 要重载的运算符(形参表)
成员运算符函数的原型在类的内部声明格式如下:
class X {
//…
返回类型 operator运算符(形参表);
//…
}
在类外定义成员运算符函数的格式如下:
返回类型 X::operator运算符(形参表)
{
函数体
}
用成员函数重载运算符:
一元运算符: Object op
解释为:Object . operator op ()操作数由对象Object通过this指针隐含传递,括号里不用写形参,因为一元运算符只需要一个操作数,而这个操作数有对象Object通过this指针隐含传递。那要是二元运算符则括号里再加一个操作数。
二元运算符:ObjectL op ObjectR
解释为:
ObjectL . operator op ( ObjectR )
左操作数由ObjectL通过this指针传递,右操作数由参数ObjectR传递。
使用注意:重载 + 二元运算符,使用时可以a+b(隐式调用);就相当于a.operator+b(显式调用);前者使用起来比较方便。
用友元函数重载运算符:(因为友元函数里面没有this指针,和成员函数重载对比来说,要多一个操作数。)
一元运算符:Object op
解释为:
operator op (Object) 操作数由参数表的参数Object提供
二元运算符;ObjectL op ObjectR
解释为:
operator op ( ObjectL, ObjectR )
左右操作数都由参数传递
特殊运算符:①= () [] ->这些运算符只能用成员函数重载,不能用友元函数重载
②成员运算符函数比友元运算符函数少带一个参数(后置的++、--需要增加一个形参)。
③双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但当操作数类型不相同时,必须使用友元函数。
④设A Aobject 运算符 ++和 - - 有两种方式:
前置方式: ++Aobject --Aobject
成员函数重载A :: A operator++ () ;
解释为:Aobject . operator ++( ) ;
友元函数重载friend A operator++ (A &) ;
解释为: operator ++( Aobject ) ;
后置方式: Aobject ++ Aobject --
成员函数重载 A :: A operator++ (int) ;
解释为: Aobject . operator ++( 0 ) ;
友元函数重载: friend A operator++ (A &, int) ;
解释为: operator++(Aobject, 0)
为了区别前置与后置,后置的时候多一个无关参数,比如上面的int,这些都可以表明是后置,他们在运行中没有其他的作用。
二 重载输入输出运算符
注意①输入输出运算符只能利用友元函数重载。
格式:输出运算符
ostream& operator<<(ostream& out,class_name& obj)
{
out<<obj.item1;
out<<obj.item2;
.. .
out<<obj.itemn;
return out;
}
输入运算符
istream& operator>>(istream& in,class_name& obj)
{
in>>obj.item1;
in>>obj.item2;
. . .
in>>obj.itemn;
return in;
}
重载输入输出运算符以后可以输出一组符合自己要求的数据,用起来很方便,解决问题也很便捷。
例题:#include<bits/stdc++.h>
using namespace std;
class Time
{private:int month;
int day;
int hour;
int minute;
public:Time()
{
month=0,day=0,hour=0,minute=0;
}
Time(int m,int d,int h,int min):month(m),day(d),hour(h),minute(min){}
void display();
void setMonth(int m){month=m;}
void setDay(int d){day=d;}
void setHour(int h){hour=h;}
void setMinute(int min){minute=min;}
int getMonth()
{
return month;
}
int getDay()
{
return day;
}
int getHour()
{
return hour;
}
int getMinute()
{
return minute;
}
void set();
};
void Time::set()
{
cin>>month>>day>>hour>>minute;
}
void Time::display()
{
cout<<month<<" "<<day<<" "<<hour<<" "<<minute<<endl;
}
int main()
{
int a,b,c,d;
cin>>a>>b>>c>>d;
Time t1(a,b,c,d);
Time t2;
t2.set();
t1.display();
t2.display();
}
重载输入输出运算符后:#include<bits/stdc++.h>
using namespace std;
class Time
{private:int month;
int day;
int hour;
int minute;
public:Time()
{
month=0,day=0,hour=0,minute=0;
}
Time(int m,int d,int h,int min):month(m),day(d),hour(h),minute(min){}
friend ostream&operator<<(ostream&os,const Time&t);
friend istream&operator>>(istream&is,Time&t);
bool operator<(const Time&t3)
const{return month!=t3.month?month<t3.month:day!=t3.day?day<t3.day:hour!=t3.hour?hour<t3.hour:minute<t3.minute;}
int getMonth()
{
return month;
}
int getDay()
{
return day;
}
int getHour()
{
return hour;
}
int getMinute()
{
return minute;
}
};
ostream&operator<<(ostream&os,const Time&t)
{
os<<t.month<<" ";
os<<t.day<<" ";
os<<t.hour<<" ";
os<<t.minute<<" ";
return os;
}
istream&operator>>(istream&is,Time&t)
{
is>>t.month>>t.day>>t.hour>>t.minute;
return is;
}
int main()
{
Time t1;
cin>>t1;
Time t2;
cin>>t2;
cout<<t1<<endl;
cout<<t2;
}
从这两个程序可以看出重载以后,代码不仅减少了,主函数写起来也很方便,也能为后面其他程序的编写减少困难。
三 通过重载运算符可以减轻很多工作,有的复杂的比较,比如时间比较,如果不重载小于号,虽然能写出来,但很麻烦,重载一个小于号就可以进行比较,不仅快,而且高效,同时重载运算符对后面的STL也是很重要的,不会重载运算符小于号对后面的学习也很困难,这一节内容不是很繁琐,就那几个套路,几个模板,掌握几个套路几个模板,运用起来也会很熟练。