运算符重载
-
一个例子
//mytime0.h #ifndef MYTIME0_H_INCLUDED #define MYTIME0_H_INCLUDED class Time { private: int hours; int minutes; public: Time(){hours=minutes=0;} Time(int h,int m=0){hours=h+m/60;minutes=m%60;} void show()const{std::cout<<hours<<" hours, "<<minutes<<" minutes\n";} //operator Time operator+(const Time &t)const//返回类型不要使用引用 { Time sum; sum.minutes=minutes+t.minutes; sum.hours=hours+t.hours; sum.hours=sum.hours+sum.minutes/60; sum.minutes%=60; return sum; } Time operator*(const int &v)const//另一种重载方式,非同类型重载 { return Time(hours*v,minutes*v); } }; #endif // MYTIME0_H_INCLUDED //main.cpp #include<bits/stdc++.h> #include"mytime0.h" using namespace std; int main() { Time thetime=Time(12,15); thetime.show(); Time lxttime=Time(11,5); thetime=thetime+lxttime; thetime.show(); }
-
重载限制
- 重载后的运算符必须至少一个操作数是用户定义的类型
- 使用运算符重载不能违反运算符原来的句法规则 – 操作数的个数 和 优先级
- 不能创建新运算符
- 有些运算符不能重载 – 可百度一下
- 有些运算符只能通过成员函数重载 – 而不能通过非成员函数重载
- = ,() , [] , ->
友元函数
- 重载遗留下的问题
thetime=thetime*2;//allowed thetime=2*thetime;//not allowed
我们只能使用非成员函数解决改问题,但常规非成员函数不能访问私有成员,只有一类特殊的非成员函数可以访问类的私有成员-友元函数。
-
声明
- 原型放在类中,但不是类成员函数,不用使用::
- 前加friend,定义不用加,可访问类的私有成员。
friend Time operator*(double m,const Time &t);
-
定义
- 不用加friend
- 不用加 类名::
-
常见的友元函数
ostream & operator<<(ostream & os,const c_name &obj) { os << ...; return os; }
-
改进后的Time类
#ifndef MYTIME0_H_INCLUDED #define MYTIME0_H_INCLUDED #include<iostream> class Time { private: int hours; int minutes; public: Time(){hours=minutes=0;} Time(int h,int m=0){hours=h+m/60;minutes=m%60;} void show()const{std::cout<<hours<<" hours, "<<minutes<<" minutes\n";} //operator Time operator+(const Time &t)const//返回类型不要使用引用 { Time sum; sum.minutes=minutes+t.minutes; sum.hours=hours+t.hours; sum.hours=sum.hours+sum.minutes/60; sum.minutes%=60; return sum; } Time operator*(const int &v)const//另一种重载方式,非同类型重载 { return Time(hours*v,minutes*v); } friend Time operator*(int v,const Time &t) { return t*v; } friend std::ostream &operator<<(std::ostream &os,const Time &t) { os<<t.hours<<" hours, "<<t.minutes<<" minutes\n"; return os; } }; #endif // MYTIME0_H_INCLUDED //main.cpp #include<bits/stdc++.h> #include"mytime0.h" using namespace std; int main() { Time thetime=Time(12,15); thetime=2*thetime;//allowed cout<<thetime<<endl; return 0; }
类的转换
- 其他类型转换成类
- 只含有一个参数的构造函数可以作为转换函数,进行自动(隐式转换)
- 构造时应避免二义性。
Time(int h);//构造函数 Time mytime; mytime=16;
- explicit关键字
- 有时候不需要这种自动特性,声明时使用该关键字即可。
explicit Time(int h) Time mytime=16;//not allowed mytime=Time(16);//allowed mytime=(Time)16;//allowed
- 有时候不需要这种自动特性,声明时使用该关键字即可。
- 该类转换成其他类型
- 应避免二义性
- 有时候会出现错误,故在声明转换函数时加上explicit,并使用显式转换。
- 或者另外声明一个成员函数来进行类型转换。
- 声明
explicit operator int() const
- 定义
Time::explicit operator int()const { return hours; }