一、运算符重载
运算符重载的含义:比如,2+3 = 5。但是如果我们想让两个数组相加,array1+array2 = array3,我们想让'+'实现两个数组中每个元素对应相加,得到array3。这个时候我们就要对+就行重载,当然也要定义一个对应的成员函数。如:
Timeoperator+(constTime & t)const;
例子源代码
/*
时间的运算,+、-和*的重载运算
*/
#ifndef MYTIME0_H_
#define MYTIME0_H_
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time & t) const;//运算符重载+
Time operator-(const Time & t) const;//运算符重载-
Time operator*(double n) const;//运算符重载*
void Show() const;
};
#endif
#include "mytime0.h"
#include <iostream>
Time::Time()//构造函数
{
hours = 0;
minutes = 0;
}
Time::Time(int h,int m)//构造函数
{
hours = h;
minutes = m;
}
void Time::AddMin(int m)//加分钟
{
minutes += m;
hours += minutes/60;
minutes = minutes%60;
}
void Time::AddHr(int h)//加小时
{
hours += h;
}
void Time::Reset(int h, int m)//时间复位,默认值是0,0。但是可以再输入对应的参数
{
hours = h;
minutes = m;
}
Time Time::operator+(const Time & t) const//+运算符重载
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours =hours + t.hours + sum.minutes/60;
sum.minutes = sum.minutes % 60;
return sum;
}
/*
将参数声明为引用的目的是为了提高效率,速度更快,使用的内存更小。
返回值不能是引用,因为如果返回类型是Time &的话,则引用的将是sum对象,
但是由于sum对象是局部变量,在函数结束时将被删除,因此引用将指向一个
不存在的对象。 返回类型是Time意味着,程序将在删除sum之前构造它的拷贝,
调用函数将得到这个拷贝。
*/
/*
不要返回指向局部变量或临时对象的引用。函数执行完毕之后,
局部变量和临时对象将消失,引用将指向不存在的数据。
*/
Time Time::operator-(const Time & t) const//重载运算符-
{
Time sub;
int m1,m2;
m1 = hours * 60 + minutes;
m2 = t.hours * 60 + t.minutes;
sub.hours = (m1 - m2)/60;
sub.minutes = (m1 - m2) % 60;
return sub;
}
Time Time::operator*(double n) const//重载运算符*
{
Time sum;
int min;
min = (hours*60 + minutes) * n;
sum.hours = min / 60;
sum.minutes = min % 60;
return sum;
}
void Time::Show() const//显示时间
{
std::cout << hours << " Hours\t" << minutes << " minutes" << std::endl;
}
#include "mytime0.h"
#include <iostream>
int main()
{
using namespace std;
Time planning;
Time coding (5, 55);
Time fixing (2, 40);
Time total;
cout << "planning time \t= "; //显示planning的时间
planning.Show();
cout << "coding time \t= ";//显示coding 的时间
coding.Show();
cout << "fixing time \t= ";//显示fixing的时间
fixing.Show();
total = coding + fixing;//求coding和fixing的和
cout << "total time \t= ";
total.Show();
cout << "将total重置时间:23小时,45分钟\n";
total.Reset(23,45);
cout << "total time \t= ";
total.Show();
total = coding - fixing;
cout << "total = coding - fixing time \t= ";//coding和fixing的差
total.Show();
total = total * 2;
cout << "total * 2 time = ";//total的时间*2
total.Show();
cin.get();
return 0;
}
二、改进
1、上例中的乘法运算,只能是 Time对象*数字,但是不能是数字*Time对象。为了实现数字*Time对象,定义了友元函数,
friend Time operator*(double m, const Time & t)
{ return t * m;}
/*
定义了友元函数,因为友元函数可以访问私有数据。
之前那个运算符重载可以实现 Time * n;
现在这个友元函数可以实现 n * Time
*/
2、上例中,显示Time对象的方法是定义了Show()方法来显示Time对象。改进,重载 << 运算符,实现 cout << Time对象;
friend std::ostream & operator<<(std::ostream & os, const Time & t);
/*
cout << time;
被转换为下面的调用形式:operator<<(cout, time);返回Time对象
可以替代Show()方法。
*/
std::ostream & operator<<(std::ostream & os, const Time & t)
{
os << t.hours << " Hours\t" << t.minutes << " minutes" << std::endl;
return os;
}
源代码
/*
时间的运算,+、-和*的重载运算
*/
#ifndef MYTIME0_H_
#define MYTIME0_H_
#include <iostream>
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time & t) const;//运算符重载+
Time operator-(const Time & t) const;//运算符重载-
Time operator*(double n) const;//运算符重载*
friend Time operator*(double m, const Time & t)
{ return t * m;}
/*
定义了友元函数,因为友元函数可以访问私有数据。
之前那个运算符重载可以实现 Time * n;
现在这个友元函数可以实现 n * Time
*/
friend std::ostream & operator<<(std::ostream & os, const Time & t);
/*
cout << time;
被转换为下面的调用形式:operator<<(cout, time);返回Time对象
可以替代Show()方法。
*/
void Show() const;
};
#endif
#include "mytime0.h"
#include <iostream>
Time::Time()//构造函数
{
hours = 0;
minutes = 0;
}
Time::Time(int h,int m)//构造函数
{
hours = h;
minutes = m;
}
void Time::AddMin(int m)//加分钟
{
minutes += m;
hours += minutes/60;
minutes = minutes%60;
}
void Time::AddHr(int h)//加小时
{
hours += h;
}
void Time::Reset(int h, int m)//时间复位,默认值是0,0。但是可以再输入对应的参数
{
hours = h;
minutes = m;
}
Time Time::operator+(const Time & t) const//+运算符重载
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours =hours + t.hours + sum.minutes/60;
sum.minutes = sum.minutes % 60;
return sum;
}
/*
将参数声明为引用的目的是为了提高效率,速度更快,使用的内存更小。
返回值不能是引用,因为如果返回类型是Time &的话,则引用的将是sum对象,
但是由于sum对象是局部变量,在函数结束时将被删除,因此引用将指向一个
不存在的对象。 返回类型是Time意味着,程序将在删除sum之前构造它的拷贝,
调用函数将得到这个拷贝。
*/
/*
不要返回指向局部变量或临时对象的引用。函数执行完毕之后,
局部变量和临时对象将消失,引用将指向不存在的数据。
*/
Time Time::operator-(const Time & t) const//重载运算符-
{
Time sub;
int m1,m2;
m1 = hours * 60 + minutes;
m2 = t.hours * 60 + t.minutes;
sub.hours = (m1 - m2)/60;
sub.minutes = (m1 - m2) % 60;
return sub;
}
Time Time::operator*(double n) const//重载运算符*
{
Time sum;
int min;
min = (hours*60 + minutes) * n;
sum.hours = min / 60;
sum.minutes = min % 60;
return sum;
}
void Time::Show() const//显示时间
{
std::cout << hours << " Hours\t" << minutes << " minutes" << std::endl;
}
std::ostream & operator<<(std::ostream & os, const Time & t)
{
os << t.hours << " Hours\t" << t.minutes << " minutes" << std::endl;
return os;
}
#include "mytime0.h"
#include <iostream>
int main()
{
using namespace std;
Time planning;
Time coding (5, 55);
Time fixing (2, 40);
Time total;
cout << "planning time \t= "; //显示planning的时间
planning.Show();
cout << "coding time \t= ";//显示coding 的时间
coding.Show();
cout << "fixing time \t= ";//显示fixing的时间
fixing.Show();
total = coding + fixing;//求coding和fixing的和
cout << "total time \t= ";
total.Show();
cout << "将total重置时间:23小时,45分钟\n";
total.Reset(23,45);
cout << "total time \t= ";
total.Show();
total = coding - fixing;
cout << "total = coding - fixing time \t= ";//coding和fixing的差
total.Show();
total = total * 2;
cout << "total * 2 time = ";//total的时间*2
total.Show();
cout << "重载'<<'运算符之后的输出:\n";
cout << "cout << total = " << total;
cout << "定义了友元函数乘法,实现了 2*total :\n";
cout << "2 * total = " << 2 * total;
cin.get();
return 0;
}