第11章 使用类

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

转换函数:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值