11.1 运算符重载
11.2 计算时间:一个运算符重载示例
mytime.h
#ifndef MYTIME_H_
#define MYTIME_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 Sum(const Time &t) const;
Time operator+(const Time &t) const;
Time operator*(double m) const;
friend Time operator*(double m,const Time &t);
void Show() const;
};
#endif
mytime.cpp
#include <iostream>
#include "mytime.h"
Time::Time()
{
hours = 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)
{
hours = h;
minutes = m;
}
Time Time::Sum(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = t.hours +hours + sum.minutes/60;
sum.minutes %= 60;
return sum;
}
Time Time::operator+(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = t.hours +hours + sum.minutes/60;
sum.minutes %= 60;
return sum;
}
Time Time::operator*(double m) const
{
Time result;
long totalmin = hours*60*m + minutes*m;
result.hours = totalmin/60;
result.minutes = totalmin%60;
return result;
}
Time operator*(double m,const Time &t)
{
/*Time result;
long totalmin = t.hours*60*m + t.minutes*m;
result.hours = totalmin/60;
result.minutes = totalmin%60;*/
return t*m;
}
void Time::Show() const
{
std::cout <<hours << " hours, " << minutes << " min\n";
}
usetime.cpp
#include <iostream>
#include "mytime.h"
Time::Time()
{
hours = 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)
{
hours = h;
minutes = m;
}
Time Time::Sum(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = t.hours +hours + sum.minutes/60;
sum.minutes %= 60;
return sum;
}
Time Time::operator+(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = t.hours +hours + sum.minutes/60;
sum.minutes %= 60;
return sum;
}
Time Time::operator*(double m) const
{
Time result;
long totalmin = hours*60*m + minutes*m;
result.hours = totalmin/60;
result.minutes = totalmin%60;
return result;
}
Time operator*(double m,const Time &t)
{
/*Time result;
long totalmin = t.hours*60*m + t.minutes*m;
result.hours = totalmin/60;
result.minutes = totalmin%60;*/
return t*m;
}
void Time::Show() const
{
std::cout <<hours << " hours, " << minutes << " min\n";
}
执行结果:
planning time:0 hours, 0 min
coding time:2 hours, 40 min
fixing time:5 hours, 55 min
total time:8 hours, 35 min
total time * 1.1:9 hours, 26 min
11.3 友元
- 友元函数
- 友元类
- 友元成员函数
创建友元
友元函数是非成员函数,但范文权限和成员函数相同
1、将其原型放在类声明中,并在原型声明前加上关键字friend
friend Time operator*(double m,const Time &t);
2、编写函数定义,应为不是成员函数,不加类限定符(time::),定义中不用关键字friend。
程序用例:
mytime3.h
#ifndef MYTIME3_H_
#define MYTIME3_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 Sum(const Time &t) const;
Time operator+(const Time &t) const;
Time operator*(double m) const;
friend Time operator*(double m,const Time &t)
{return t*m;}
//void Show() const;
friend std::ostream &operator<<(std::ostream &os,const Time &t);
};
#endif
mytime3.cpp
#include "mytime3.h"
Time::Time()
{
hours = 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)
{
hours = h;
minutes = m;
}
Time Time::Sum(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = t.hours +hours + sum.minutes/60;
sum.minutes %= 60;
return sum;
}
Time Time::operator+(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = t.hours +hours + sum.minutes/60;
sum.minutes %= 60;
return sum;
}
Time Time::operator*(double m) const
{
Time result;
long totalmin = hours*60*m + minutes*m;
result.hours = totalmin/60;
result.minutes = totalmin%60;
return result;
}
/*Time operator*(double m,const Time &t)
{
Time result;
long totalmin = t.hours*60*m + t.minutes*m;
result.hours = totalmin/60;
result.minutes = totalmin%60;
return t*m;
}*/
/*void Time::Show() const
{
std::cout <<hours << " hours, " << minutes << " min\n";
}*/
std::ostream &operator<<(std::ostream &os,const Time &t)
{
os << t.hours << " hours," << t.minutes << " minutes";
return os;
}
usetime3.cpp
#include <iostream>
#include "mytime3.h"
using namespace std;
int main()
{
Time coding(3,35);
Time fixing(2,48);
Time total;
cout << "coding and fixing:" ;
cout << coding << ";" << fixing << endl;
total = coding + fixing;
cout << "coding + fixing:" << total << endl;
total = coding*1.17;
cout << "coding*1.17:" << total << endl;
cout << "10.0*fixing" << 10.0*fixing << endl;
return 0;
}
运行结果:
coding and fixing:3 hours,35 minutes;2 hours,48 minutes
coding + fixing:6 hours,23 minutes
coding*1.17:4 hours,11 minutes
10.0*fixing28 hours,0 minutes
11.4重载运算符:作为成员函数还是非成员函数
11.5再谈重载:一个矢量类
示例:
vector.h
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
namespace VECTOR
{
class Vector
{
public:
enum Mode{RECT,POL}; //状态成员 RECT直角坐标模式 POL极坐标模式
private:
double x;
double y;
double mag;
double ang;
Mode mode;
void set_mag();
void set_ang();
void set_x();
void set_y();
public:
Vector();
Vector(double n1,double n2,Mode form = RECT);
void reset(double n1,double n2,Mode form = RECT);
~Vector();
double xval() const {return x;}
double yval() const {return y;}
double magval() const {return mag;}
double angval() const {return ang;}
void polar_mode();
void rect_mode();
Vector operator+(const Vector &b) const;
Vector operator-(const Vector &b) const;
Vector operator-() const;
Vector operator*(double n) const;
friend Vector operator*(double n,const Vector &a);
friend std::ostream &operator<<(std::ostream &os,const Vector &v);
};
}
#endif
vector.cpp
#include "vector.h"
#include <cmath>
using namespace std;
namespace VECTOR
{
const double Rad_to_deg = 45.0/atan(1.0);
void Vector::set_mag()
{
mag = sqrt(x*x+y*y);
}
void Vector::set_ang()
{
if(x == 0 && y == 0)
ang = 0;
else
ang = atan2(y,x);
}
void Vector::set_x()
{
x = mag*cos(ang);
}
void Vector::set_y()
{
y = mag*sin(ang);
}
Vector::Vector()
{
x = y =mag = ang = 0;
mode = RECT;
}
Vector::Vector(double n1,double n2,Mode form)
{
mode = form;
if(form == RECT)
{
x= n1;
y =n2;
set_mag();
set_ang();
}
else if(form == POL)
{
mag = n1;
ang = n2;
set_x();
set_y();
}
else
{
cout << "incorrect argument\n";
cout << "vector set to 0";
x = y =mag = ang = 0;
mode = RECT;
}
}
void Vector::reset(double n1,double n2,Mode form)
{
mode = form;
if(form == RECT)
{
x= n1;
y =n2;
set_mag();
set_ang();
}
else if(form == POL)
{
mag = n1;
ang = n2;
set_x();
set_y();
}
else
{
cout << "incorrect argument\n";
cout << "vector set to 0";
x = y =mag = ang = 0;
mode = RECT;
}
}
Vector::~Vector()
{
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
mode = RECT;
}
Vector Vector::operator+(const Vector &b) const
{
return Vector((x+b.x),(y+b.y));
}
Vector Vector::operator-(const Vector &b) const
{
return Vector((x-b.x),(y-b.y));
}
Vector Vector::operator-() const
{
return Vector((-x),(-y));
}
Vector Vector::operator*(double n) const
{
return Vector(n*x,n*y);
}
Vector operator*(double n,const Vector &a)
{
return a*n;
}
std::ostream &operator<< (std::ostream &os,const Vector &v)
{
//
if(v.mode == Vector::RECT)
os << "(x,y) = (" << v.x << "," << v.y <<")";
else if(v.mode == Vector::POL)
{
os << "(m,a) = (" << v.mag << "," << v.ang <<")";
}
else
os << "vector is invalid";
return os;
}
}
随即漫步(醉鬼走路):
randwalk.cpp
#include "vector.h"
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
using VECTOR::Vector;
srand(time(0));
double direction;
Vector step;
Vector result(0.0,0.0);
unsigned long steps = 0;
double target;
double dstep;
cout <<"enter target distance (q to quite):";
while(cin >> target)
{
cout << "enter step length:";
if(!(cin >> dstep))
{
break;
}
while(result.magval() < target)
{
direction = rand()%360;
step.reset(dstep,direction,Vector::POL);
result = result + step;
steps++;
}
cout << "after " << steps << " steps,the subject has the following location:\n";
cout << result << endl;
result.polar_mode();
cout << "or\n" << result << endl;
cout << "average outward distance per step = " << result.magval()/steps << endl;
steps = 0;
result.reset(0.0,0.0);
cout << "enter target distance(q to quit):";
}
cout << "Byte!\n";
cin.clear();
while(cin.get()!='\n')
continue;
return 0;
}
运行结果:
enter target distance (q to quite):10
enter step length:1
after 116 steps,the subject has the following location:
(x,y) = (-3.42834,-9.68444)
or
(m,a) = (10.2734,-1.91104)
average outward distance per step = 0.0885634
enter target distance(q to quit):20
enter step length:2
after 117 steps,the subject has the following location:
(x,y) = (6.30402,19.1596)
or
(m,a) = (20.17,1.25293)
average outward distance per step = 0.172393
enter target distance(q to quit):q
Byte!
11.6类的自动转换和强制类型转换
stonewt.h
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
enum {Labs_per_stn = 14};
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
Stonewt(int stn,double lbs);
Stonewt();
~Stonewt();
void show_lbs() const;
void show_stn() const;
};
#endif
stonewt.cpp
#include <iostream>
#include "stonewt.h"
using namespace std;
Stonewt::Stonewt(double lbs)
{
stone = int (lbs)/Labs_per_stn;
pds_left = int (lbs)%Labs_per_stn +lbs - int(lbs);
pounds = lbs;
}
Stonewt::Stonewt(int stn,double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn*Labs_per_stn + lbs;
}
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
}
Stonewt::~Stonewt()
{
}
void Stonewt::show_stn() const
{
cout << stone << "stone," << pds_left << "pounds\n";
}
void Stonewt::show_lbs() const
{
cout << pounds << "pounds\n";
}
explicit:只能用于显示转换,不能用于隐式转换。
stone.cpp
#include <iostream>
#include "stonewt.h"
using namespace std;
void display(const Stonewt &st,int n);
int main()
{
Stonewt incognito = 275;
Stonewt wolfe(285.7);
Stonewt taft(21,8);
cout << "the celebrity weighed ";
incognito.show_stn();
cout << "the detective weighed ";
wolfe.show_stn();
cout << "the president weighed ";
taft.show_lbs();
incognito = 276.8;
taft = 325;
cout << "after dinner,the celebrity weighed ";
incognito.show_stn();
cout << "after dinner,the president weighed ";
taft.show_lbs();
display(taft,2);
cout << "the wrestler weiged even more.\n";
display(422,2);
cout << "No stone left unearned\n";
return 0;
}
void display(const Stonewt &st,int n)
{
for(int i = 0;i<n;i++)
{
cout << "Wow| ";
st.show_stn();
}
}
运行结果:
the celebrity weighed 19stone,9pounds
the detective weighed 20stone,5.7pounds
the president weighed 302pounds
after dinner,the celebrity weighed 19stone,10.8pounds
after dinner,the president weighed 325pounds
Wow| 23stone,3pounds
Wow| 23stone,3pounds
the wrestler weiged even more.
Wow| 30stone,2pounds
Wow| 30stone,2pounds
No stone left unearned
转换函数: