2021-01-12 C++ Primer Plus 第十一章 使用类 编程练习

编程练习

1.修改程序11.5,使之将一系列连续的随机漫步者位置写入到文件中。

vect.h

#ifndef RANDWALK_VECT_H
#define RANDWALK_VECT_H
#include 
namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode {RECT, POL};
        // RECT for rectangular, POL for Polar modes
    private:
        double x;          // horizontal value
        double y;          // vertical value
        double mag;        // length of vector
        double ang;        // direction of vector in degrees
        Mode mode;         // RECT or POL
        // private methods for setting values
        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;}       // report x value
        double yval() const {return y;}       // report y value
        double magval() const {return mag;}   // report magnitude
        double angval() const {return ang;}   // report angle
        void polar_mode();                    // set mode to POL
        void rect_mode();                     // set mode to RECT
        // operator overloading
        Vector operator+(const Vector & b) const;
        Vector operator-(const Vector & b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        // friends
        friend Vector operator*(double n, const Vector & a);
        friend std::ostream & operator<<(std::ostream & os, const Vector & v);
    };

}   // end namespace VECTOR
#endif //RANDWALK_VECT_H

vect.cpp

// vect.cpp -- methods for the Vector class
#include 
#include "vect.h"   // includes 
#include 
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout,std::endl;
using std::ofstream;

namespace VECTOR
{
    // compute degrees in one radian
    const double Rad_to_deg = 45.0 / atan(1.0);
    // should be about 57.2957795130823

    // private methods
    // calculates magnitude from x and y
    void Vector::set_mag()
    {
        mag = sqrt(x * x + y * y);
    }

    void Vector::set_ang()
    {
        if (x == 0.0 && y == 0.0)
            ang = 0.0;
        else
            ang = atan2(y, x);
    }

    // set x from polar coordinate
    void Vector::set_x()
    {
        x = mag * cos(ang);
    }

    // set y from polar coordinate
    void Vector::set_y()
    {
        y = mag * sin(ang);
    }

    // public methods
    Vector::Vector()             // default constructor
    {
        x = y = mag = ang = 0.0;
        mode = RECT;
    }

    // construct vector from rectangular coordinates if form is r
    // (the default) or else from polar coordinates if form is p
    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 / Rad_to_deg;
            set_x();
            set_y();
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0.0;
            mode = RECT;
        }
    }

    // reset vector from rectangular coordinates if form is
    // RECT (the default) or else from polar coordinates if
    // form is POL
    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 / Rad_to_deg;
            set_x();
            set_y();
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0.0;
            mode = RECT;
        }
    }

    Vector::~Vector()    // destructor
    {
    }

    void Vector::polar_mode()    // set to polar mode
    {
        mode = POL;
    }

    void Vector::rect_mode()     // set to rectangular mode
    {
        mode = RECT;
    }

    // operator overloading
    // add two Vectors
    Vector Vector::operator+(const Vector & b) const
    {
        return Vector(x + b.x, y + b.y);
    }

    // subtract Vector b from a
    Vector Vector::operator-(const Vector & b) const
    {
        return Vector(x - b.x, y - b.y);
    }

    // reverse sign of Vector
    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }

    // multiply vector by n
    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }

    // friend methods
    // multiply n by Vector a
    Vector operator*(double n, const Vector & a)
    {
        return a * n;
    }
    // display rectangular coordinates if mode is RECT,
    // else display polar coordinates if mode is POL
    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 * Rad_to_deg << ")";
        }
        else
            os << "Vector object mode is invalid";
        return os;
    }

}  // end namespace VECTOR

main.cpp

// vect.cpp -- methods for the Vector class
#include 
#include "vect.h"   // includes 
#include 
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout,std::endl;
using std::ofstream;

namespace VECTOR
{
    // compute degrees in one radian
    const double Rad_to_deg = 45.0 / atan(1.0);
    // should be about 57.2957795130823

    // private methods
    // calculates magnitude from x and y
    void Vector::set_mag()
    {
        mag = sqrt(x * x + y * y);
    }

    void Vector::set_ang()
    {
        if (x == 0.0 && y == 0.0)
            ang = 0.0;
        else
            ang = atan2(y, x);
    }

    // set x from polar coordinate
    void Vector::set_x()
    {
        x = mag * cos(ang);
    }

    // set y from polar coordinate
    void Vector::set_y()
    {
        y = mag * sin(ang);
    }

    // public methods
    Vector::Vector()             // default constructor
    {
        x = y = mag = ang = 0.0;
        mode = RECT;
    }

    // construct vector from rectangular coordinates if form is r
    // (the default) or else from polar coordinates if form is p
    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 / Rad_to_deg;
            set_x();
            set_y();
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0.0;
            mode = RECT;
        }
    }

    // reset vector from rectangular coordinates if form is
    // RECT (the default) or else from polar coordinates if
    // form is POL
    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 / Rad_to_deg;
            set_x();
            set_y();
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0.0;
            mode = RECT;
        }
    }

    Vector::~Vector()    // destructor
    {
    }

    void Vector::polar_mode()    // set to polar mode
    {
        mode = POL;
    }

    void Vector::rect_mode()     // set to rectangular mode
    {
        mode = RECT;
    }

    // operator overloading
    // add two Vectors
    Vector Vector::operator+(const Vector & b) const
    {
        return Vector(x + b.x, y + b.y);
    }

    // subtract Vector b from a
    Vector Vector::operator-(const Vector & b) const
    {
        return Vector(x - b.x, y - b.y);
    }

    // reverse sign of Vector
    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }

    // multiply vector by n
    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }

    // friend methods
    // multiply n by Vector a
    Vector operator*(double n, const Vector & a)
    {
        return a * n;
    }
    // display rectangular coordinates if mode is RECT,
    // else display polar coordinates if mode is POL
    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 * Rad_to_deg << ")";
        }
        else
            os << "Vector object mode is invalid";
        return os;
    }

}  // end namespace VECTOR

randwalk.txt

Target Distance: 100, Step Size: 20
0: (x,y) = (0,0)
1: (x,y) = (-17.8201,9.07981)
2: (x,y) = (-35.1406,-0.92019)
3: (x,y) = (-18.3672,9.97259)
4: (x,y) = (-37.8546,14.4716)
5: (x,y) = (-48.453,-2.48935)
6: (x,y) = (-29.5426,-9.00071)
7: (x,y) = (-39.2388,-26.4931)
8: (x,y) = (-23.0585,-38.2488)
9: (x,y) = (-41.9689,-44.7602)
10: (x,y) = (-23.0585,-38.2488)
11: (x,y) = (-4.6484,-30.4342)
12: (x,y) = (10.4458,-17.313)
13: (x,y) = (-6.51517,-6.71462)
14: (x,y) = (-22.8982,-18.1862)
15: (x,y) = (-2.91039,-18.8841)
16: (x,y) = (-5.00096,-38.7746)
17: (x,y) = (13.5427,-31.2824)
18: (x,y) = (-1.32018,-44.6651)
19: (x,y) = (-21.2715,-43.2699)
20: (x,y) = (-3.77907,-52.9661)
21: (x,y) = (10.848,-66.6061)
22: (x,y) = (12.9386,-46.7157)
23: (x,y) = (31.4823,-39.2235)
24: (x,y) = (43.7955,-23.4633)
25: (x,y) = (61.116,-33.4633)
26: (x,y) = (56.617,-52.9507)
27: (x,y) = (53.8335,-33.1453)
28: (x,y) = (50.3605,-52.8415)
29: (x,y) = (58.8129,-70.9677)
30: (x,y) = (44.6708,-56.8255)
31: (x,y) = (28.9106,-44.5123)
32: (x,y) = (16.3242,-28.9694)
33: (x,y) = (-0.636812,-39.5678)
34: (x,y) = (-20.0427,-44.4062)
35: (x,y) = (-3.26931,-33.5134)
36: (x,y) = (-10.4367,-52.185)
37: (x,y) = (-24.0766,-66.8121)
38: (x,y) = (-24.7746,-46.8243)
39: (x,y) = (-42.0951,-36.8243)
40: (x,y) = (-49.9098,-18.4142)
41: (x,y) = (-63.5497,-3.78711)
42: (x,y) = (-83.5223,-4.83383)
After 43 steps, the subject has the following location:
(x,y) = (-103.328, -2.05037)
 or
(m,a) = (103.348, -178.863)
Average outward distance per step = 2.40344

2.对Vector类的头文件和实现文件进行修改,使其不再存储矢量的长度和角度,而是在magval()和angval()被调用时计算他们。

vect.h

#ifndef RANDWALK_VECT_H
#define RANDWALK_VECT_H
#include 
namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode {RECT, POL};
        // RECT for rectangular, POL for Polar modes
    private:
        double x;          // horizontal value
        double y;          // vertical value
        Mode mode;         // RECT or POL
        // private methods for setting values
        double set_mag() const;
        double set_ang() const;
        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;}       // report x value
        double yval() const {return y;}       // report y value
        double magval() const  {return set_mag();}   // report magnitude
        double angval() const {return set_ang();}   // report angle
        void polar_mode();                    // set mode to POL
        void rect_mode();                     // set mode to RECT
        // operator overloading
        Vector operator+(const Vector & b) const;
        Vector operator-(const Vector & b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        // friends
        friend Vector operator*(double n, const Vector & a);
        friend std::ostream & operator<<(std::ostream & os, const Vector & v);
    };

}   // end namespace VECTOR
#endif //RANDWALK_VECT_H

vect.cpp

// vect.cpp -- methods for the Vector class
#include 
#include "vect.h"   // includes 
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;

namespace VECTOR
{
    // compute degrees in one radian
    const double Rad_to_deg = 45.0 / atan(1.0);
    // should be about 57.2957795130823

    // private methods
    // calculates magnitude from x and y
    double Vector::set_mag() const
    {
        return sqrt(x * x + y * y);
    }
//
    double Vector::set_ang() const
    {
        if (x == 0.0 && y == 0.0)
            return 0.0;
        else
            return atan2(y, x);
    }

    // set x from polar coordinate
    void Vector::set_x()
    {
        x = set_mag() * cos(set_ang());
    }

    // set y from polar coordinate
    void Vector::set_y()
    {
        y = set_mag() * sin(set_ang());
    }

    // public methods
    Vector::Vector()             // default constructor
    {
        x = y = 0.0;
        mode = RECT;
    }

    // construct vector from rectangular coordinates if form is r
    // (the default) or else from polar coordinates if form is p
    Vector::Vector(double n1, double n2, Mode form)
    {
        mode = form;
        if (form == RECT)
        {
            x = n1;
            y = n2;

        }
        else if (form == POL)
        {
            double mag = n1;
            double ang = n2 / Rad_to_deg;
            x = mag * cos(ang);
            y = mag * sin(ang);
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y =0.0;
            mode = RECT;
        }
    }

    // reset vector from rectangular coordinates if form is
    // RECT (the default) or else from polar coordinates if
    // form is POL
    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)
        {
            double mag = n1;
            double ang = n2 / Rad_to_deg;
            x = mag * cos(ang);
            y = mag * sin(ang);
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = 0.0;
            mode = RECT;
        }
    }

    Vector::~Vector()    // destructor
    {
    }

    void Vector::polar_mode()    // set to polar mode
    {
        mode = POL;
    }

    void Vector::rect_mode()     // set to rectangular mode
    {
        mode = RECT;
    }

    // operator overloading
    // add two Vectors
    Vector Vector::operator+(const Vector & b) const
    {
        return Vector(x + b.x, y + b.y);
    }

    // subtract Vector b from a
    Vector Vector::operator-(const Vector & b) const
    {
        return Vector(x - b.x, y - b.y);
    }

    // reverse sign of Vector
    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }

    // multiply vector by n
    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }

    // friend methods
    // multiply n by Vector a
    Vector operator*(double n, const Vector & a)
    {
        return a * n;
    }
    //show the coordinates of RECT

    // display rectangular coordinates if mode is RECT,
    // else display polar coordinates if mode is POL
    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.magval() << ", "
               << v.angval() * Rad_to_deg << ")";
        }
        else
            os << "Vector object mode is invalid";
        return os;
    }

}  // end namespace VECTOR

main.cpp

// randwalk.cpp -- using the Vector class
// compile with the vect.cpp file
#include 
#include       // rand(), srand() prototypes
#include         // time() prototype
#include "vect.h"
int main()
{
    using namespace std;
    using VECTOR::Vector;
    srand(time(0));     // seed random-number generator
    double direction;
    Vector step;
    Vector result(0.0, 0.0);
    unsigned long steps = 0;
    double target;
    double dstep;
    cout << "Enter target distance (q to quit): ";
    while (cin >> target)
    {
        cout << "Enter step length: ";
        if (!(cin >> dstep))
            break;

        while (result.magval() < target) //magval return vector length
        {
            direction = rand() % 360;
            step.reset(dstep, direction, VECTOR::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 << "Bye!\n";
/* keep window open
    cin.clear();
    while (cin.get() != '\n')
        continue;
    cin.get();
*/
    return 0;
}

3.修稿程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数而不是报告每次测试的结果。

vect.h

#ifndef RANDWALK_VECT_H
#define RANDWALK_VECT_H
#include 
namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode {RECT, POL};
        // RECT for rectangular, POL for Polar modes
    private:
        double x;          // horizontal value
        double y;          // vertical value
        Mode mode;         // RECT or POL
        // private methods for setting values
        double set_mag() const;
        double set_ang() const;
        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;}       // report x value
        double yval() const {return y;}       // report y value
        double magval() const  {return set_mag();}   // report magnitude
        double angval() const {return set_ang();}   // report angle
        void polar_mode();                    // set mode to POL
        void rect_mode();                     // set mode to RECT

        // operator overloading
        Vector operator+(const Vector & b) const;
        Vector operator-(const Vector & b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        // friends
        friend Vector operator*(double n, const Vector & a);
        friend std::ostream & operator<<(std::ostream & os, const Vector & v);
    };

}   // end namespace VECTOR
#endif //RANDWALK_VECT_H

vect.cpp

// vect.cpp -- methods for the Vector class
#include 
#include "vect.h"   // includes 
#include       // rand(), srand() prototypes
#include         // time() prototype

using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;

namespace VECTOR
{
    // compute degrees in one radian
    const double Rad_to_deg = 45.0 / atan(1.0);
    // should be about 57.2957795130823

    // private methods
    // calculates magnitude from x and y
    double Vector::set_mag() const
    {
        return sqrt(x * x + y * y);
    }
//
    double Vector::set_ang() const
    {
        if (x == 0.0 && y == 0.0)
            return 0.0;
        else
            return atan2(y, x);
    }

    // set x from polar coordinate
    void Vector::set_x()
    {
        x = set_mag() * cos(set_ang());
    }

    // set y from polar coordinate
    void Vector::set_y()
    {
        y = set_mag() * sin(set_ang());
    }

    // public methods
    Vector::Vector()             // default constructor
    {
        x = y = 0.0;
        mode = RECT;
    }

    // construct vector from rectangular coordinates if form is r
    // (the default) or else from polar coordinates if form is p
    Vector::Vector(double n1, double n2, Mode form)
    {
        mode = form;
        if (form == RECT)
        {
            x = n1;
            y = n2;

        }
        else if (form == POL)
        {
            double mag = n1;
            double ang = n2 / Rad_to_deg;
            x = mag * cos(ang);
            y = mag * sin(ang);
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y =0.0;
            mode = RECT;
        }
    }

    // reset vector from rectangular coordinates if form is
    // RECT (the default) or else from polar coordinates if
    // form is POL
    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)
        {
            double mag = n1;
            double ang = n2 / Rad_to_deg;
            x = mag * cos(ang);
            y = mag * sin(ang);
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = 0.0;
            mode = RECT;
        }
    }

    Vector::~Vector()    // destructor
    {
    }

    void Vector::polar_mode()    // set to polar mode
    {
        mode = POL;
    }

    void Vector::rect_mode()     // set to rectangular mode
    {
        mode = RECT;
    }

    // operator overloading
    // add two Vectors
    Vector Vector::operator+(const Vector & b) const
    {
        return Vector(x + b.x, y + b.y);
    }

    // subtract Vector b from a
    Vector Vector::operator-(const Vector & b) const
    {
        return Vector(x - b.x, y - b.y);
    }

    // reverse sign of Vector
    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }

    // multiply vector by n
    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }

    // friend methods
    // multiply n by Vector a
    Vector operator*(double n, const Vector & a)
    {
        return a * n;
    }


    // display rectangular coordinates if mode is RECT,
    // else display polar coordinates if mode is POL
    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.magval() << ", "
               << v.angval() * Rad_to_deg << ")";
        }
        else
            os << "Vector object mode is invalid";
        return os;
    }

}  // end namespace VECTOR

main.cpp

#include 
#include "vect.h"

void Test(int);
int main()
{

    unsigned long N;
    std::cout << "Enter epoch N : ";
    std::cin >> N;
    Test(N);
}
void Test(int N)
{
    using VECTOR::Vector;
    using namespace std;
    srand(time(0));     // seed random-number generator
    double direction;
    Vector step;
    Vector result(0.0, 0.0);
    unsigned long steps[N];
    for(int i=0;i> target) {
        cout << "Enter step length: ";
        if (!(cin >> dstep))
            break;

        while (result.magval() < target) //magval return vector length
        {
            direction = rand() % 360;
            step.reset(dstep, direction, VECTOR::Vector::POL);
            result = result + step;
            steps[count]++;
        }
        Max_Step=steps[0];
        Min_Step=steps[0];
        Sum_Step=0;

        if(steps[count]>Max_Step)
            Max_Step=steps[count];
        if (steps[count]

4.重新编写最后的Time类实例(程序清单11.10、程序清单11.11和程序清单11.12),使用友元函数来实现所有的重载运算符。

mytime3.h

#include 

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);
    friend Time operator+(const Time & t,const Time &s);
    friend Time operator-(const Time & t,const Time &s);
    friend Time operator*(double m,const Time & t);
    friend Time operator*(const Time & t,double m)
    { return m*t; }   // inline definition
    friend std::ostream & operator<<(std::ostream & os, const Time & t);

};

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 %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}

Time operator+(const Time & t,const Time & s)
{
    Time sum;
    sum.minutes = s.minutes + t.minutes;
    sum.hours = s.hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}

Time operator-(const Time & s,const Time & t)
{
    Time diff;
    int tot1, tot2;
    tot1 = t.minutes + 60 * t.hours;
    tot2 = s.minutes + 60 * s.hours;
    diff.minutes = (tot2 - tot1) % 60;
    diff.hours = (tot2 - tot1) / 60;
    return diff;
}

Time operator*(double m , const Time &t)
{
    Time result;
    long totalminutes = t.hours * m * 60 + t.minutes * m;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;
    return result;
}

std::ostream & operator<<(std::ostream & os, const Time & t)
{
    os << t.hours << " hours, " << t.minutes << " minutes";
    return os;
}

main.cpp

#include 
#include "mytime3.h"

int main()
{
    using std::cout;
    using std::endl;
    Time aida(3, 35);
    Time tosca(2, 48);
    Time temp;

    cout << "Aida and Tosca:\n";
    cout << aida <<"; " << tosca << endl;
    temp = aida + tosca;     // operator+()
    cout << "Aida + Tosca: " << temp << endl;

    temp = aida -tosca;
    cout << "Aida - Tosca: " << temp << endl;

    temp = aida * 1.17;  // member operator*()
    cout << "Aida * 1.17: " << temp << endl;
    cout << "10.0 * Tosca: " << 10.0 * tosca << endl;

    return 0;
}

5.重新编写Stonewt类 ,使它有一个状态成员,由该成员控制对象应转换为英石格式、整数磅还是浮点数磅格式。重载<<运算符,使用它来替换show_stn()和show_lbs()方法。重载加法、减法和乘法运算符,以便可以对Stonewt值进行加、减、乘运算。编写一个使用所有类方法和友元的小程序,来测试这个类。

stonewt.h

#ifndef CLASS_STONEWT_H
#define CLASS_STONEWT_H
#include 
class Stonewt
{
public:
    enum Mode {ST,FLOAT_PD,INT_PD};
private:
    static const int Lbs_per_stn=14;
    int stone;
    double pds_left;
    double pounds;
    Mode mode;
public:
    Stonewt(double lbs,Mode form);
    Stonewt(int stn,double lbs,Mode form);
    Stonewt();
    ~Stonewt();
    void set_mode(Mode form){mode=form;};
    Stonewt operator+(const Stonewt &s) const;
    Stonewt operator-(const Stonewt &s) const;
    friend Stonewt operator*(double mult,const Stonewt &s);
    friend Stonewt operator*(const Stonewt &s,double mult)
    {return mult*s;}
    friend std::ostream & operator<<(std::ostream & os,const Stonewt &s);
};
#endif //CLASS_STONEWT_H

stonewt.cpp

#include 
#include "stonewt.h"

using std::cout;

Stonewt::Stonewt(double lbs,Mode form=ST) {
    mode = form;
    pounds=lbs;
    stone=int(lbs)/Lbs_per_stn;
    pds_left=int(lbs)%Lbs_per_stn +lbs - int(lbs);

}

Stonewt::Stonewt(int stn, double lbs ,Mode form=ST) {
    mode = form;
    pounds = stn * Lbs_per_stn + lbs;
    stone = stn;
    pds_left = lbs;
}

Stonewt::Stonewt() {
    pds_left=pounds=stone=0;
    mode = ST;
}
Stonewt::~Stonewt()
{
}
Stonewt Stonewt::operator+(const Stonewt &s) const
{
    return Stonewt(s.pounds+pounds);
}
Stonewt Stonewt::operator-(const Stonewt &s) const
{
    return Stonewt(pounds-s.pounds);
}
Stonewt operator*(double mult,const Stonewt &s)
{
    return Stonewt(s.stone*mult*s.Lbs_per_stn+s.pds_left*mult);
}

std::ostream &operator<<(std::ostream &os, const Stonewt &s)
{
    if (s.mode==Stonewt::FLOAT_PD)
        os << "FLOAT pounds: " << s.pounds << "\n";
    else if(s.mode==Stonewt::INT_PD)
        os << "INT pounds: " << int(s.pounds) << "\n";
    else if(s.mode==Stonewt::ST)
        os << s.stone << " stone, " << s.pds_left << " pounds\n";
    return os;
}

main.cpp

#include 
using std::cout;
#include "stonewt.h"

void display(const Stonewt & st,int n);
int main()
{
    using std::cout,std::endl;
    Stonewt p1(1,13,Stonewt::ST);
    cout <<"p1 weight: "<< p1;
    p1.set_mode(Stonewt::INT_PD);
    cout <

6.重新编写Stonewt类,重载全部六个关系运算符,运算符对pounds成员进行比较,并返回一个bool值。编写一个程序,它声明一个包含6个Stonewt对象的数组,并在数组声明中初始化前3个对象。然后用循环来读取用于设置3个数组元素的值。接着报告最小的元素、最大的元素。接着报告最小的元素、最大的元素以及等于11英石的元素的数量

stonewt.h

#ifndef CLASS_STONEWT_H
#define CLASS_STONEWT_H
#include 
class Stonewt
{
public:
    enum Mode {ST,FLOAT_PD,INT_PD};
private:
    static const int Lbs_per_stn=14;
    int stone;
    double pds_left;
    double pounds;
    Mode mode;
public:
    Stonewt(double lbs,Mode form=ST);
    Stonewt(int stn,double lbs,Mode form=ST);
    Stonewt();
    ~Stonewt();
    void set_mode(Mode form){mode=form;};
    bool pounds_11();
    bool operator<(const Stonewt &s) const
    {return pounds(const Stonewt &s) const
    {return pounds>s.pounds;};
    bool operator==(const Stonewt &s) const
    {return pounds==s.pounds;};
    bool operator!=(const Stonewt &s) const
    {return pounds!=s.pounds;};
    bool operator<=(const Stonewt &s) const
    {return pounds<=s.pounds;};
    bool operator>=(const Stonewt &s) const
    {return pounds>=s.pounds;};

    friend std::ostream & operator<<(std::ostream & os,const Stonewt &s);
};
#endif //CLASS_STONEWT_H

stonewt.cpp

#include 
#include "stonewt.h"

using std::cout;

Stonewt::Stonewt(double lbs,Mode form) {
    mode = form;
    pounds=lbs;
    stone=int(lbs)/Lbs_per_stn;
    pds_left=int(lbs)%Lbs_per_stn +lbs - int(lbs);

}

Stonewt::Stonewt(int stn, double lbs ,Mode form) {
    mode = form;
    pounds = stn * Lbs_per_stn + lbs;
    stone = stn;
    pds_left = lbs;
}

Stonewt::Stonewt() {
    pds_left=pounds=stone=0;
    mode = ST;
}
Stonewt::~Stonewt()
{
}
bool Stonewt::pounds_11() {
    if(pounds>=11)
        return true;
}

std::ostream &operator<<(std::ostream &os, const Stonewt &s)
{
    if (s.mode==Stonewt::FLOAT_PD)
        os << "FLOAT pounds: " << s.pounds << "\n";
    else if(s.mode==Stonewt::INT_PD)
        os << "INT pounds: " << int(s.pounds) << "\n";
    else if(s.mode==Stonewt::ST)
        os << s.stone << " stone, " << s.pds_left << " pounds\n";
    return os;
}

main.cpp

#include 
using std::cout,std::cin;
#include "stonewt.h"

void compare(Stonewt *s);
int main()
{
    using std::cout,std::endl;
    Stonewt list[6]={
            Stonewt(1,2),
            Stonewt(2,4),
            Stonewt(3,6),
    };

    for(int i = 3;i<6;i++)
    {
        int stn;
        double lbs;
        cout << "stn: ";
        cin >>stn;
        cout << "lbs: ";
        cin >> lbs;
        list[i]=Stonewt(stn,lbs);
    }
    compare(list);
}
void compare(Stonewt *s)
{
    Stonewt Max=s[0];
    Stonewt Min=s[0];
    unsigned int count=0;
    for (int i = 0; i < 6; ++i) {
        if (s[i].pounds_11())
            count++;
        if(s[i]>Max)
            Max=s[i];
        if(s[i]

7.复数有两个部分组成:实数部分和虚数部分。复数的一种书写方式是:(3.0,4.0),其中,3.0是实数部分,4.0是虚数部分。

complex0.h

#ifndef COMPLEX_COMPLEX0_H
#define COMPLEX_COMPLEX0_H
#include 
class Complex0
{
private:
    double real;
    double imaginary;
public:
    Complex0();
    Complex0(double r,double i);
    Complex0 operator~() const;
    Complex0 operator+(Complex0 &c) const;
    Complex0 operator-(Complex0 &c) const;
    Complex0 operator*(Complex0 &c) const;

    friend Complex0 operator*(double mult,Complex0 &c);

    friend std::ostream & operator<<(std::ostream &os,const Complex0 & c);
    friend std::istream & operator>>(std::istream &is,Complex0 & c);
};
#endif //COMPLEX_COMPLEX0_H

complex0.cpp

#include 
#include "complex0.h"

Complex0::Complex0() {
    real=imaginary=0;
}
Complex0::Complex0(double r, double i) {
    real=r;
    imaginary=i;
}

Complex0 Complex0::operator+(Complex0 &c) const {
    return Complex0(real+c.real,imaginary+c.imaginary);
}

Complex0 Complex0::operator-(Complex0 &c) const {
    return Complex0(real-c.real,imaginary-c.imaginary);
}

Complex0 Complex0::operator*(Complex0 &c) const {
    Complex0 res;
    res.real=real*c.real-imaginary*c.imaginary;
    res.imaginary=real*c.imaginary+imaginary*c.real;
    return res;
}

Complex0 Complex0::operator~() const {
    return Complex0(real,-imaginary);
}

Complex0 operator*(double mult,Complex0 &c){
    return Complex0(mult*c.real,mult*c.imaginary);
}

std::ostream & operator<<(std::ostream &os,const Complex0 & c)
{
    os << " (" << c.real << "," << c.imaginary << "i)\n";
}
std::istream & operator>>(std::istream &is,Complex0 & c)
{
    std::cout << "real:";
    is >> c.real;
    std::cout << "imaginary:";
    is >> c.imaginary;
    return is;
}

main.cpp

#include 
using namespace std;
#include "complex0.h"

int main()
{
    Complex0 a(3.0,4.0);
    Complex0 c;
    cout << "Enter a complex number (q to quit)\n";
    while (cin >> c)
    {
        cout << "c is " << c << '\n';
        cout << "complex conjugate is " << ~c << '\n';
        cout << "a is " << a <<'\n';
        cout << "a + c is " << a+c << '\n';
        cout << "a - c is " << a-c << '\n';
        cout << "a * c is " << a*c << '\n';
        cout << "2 * c is " << 2*c << '\n';
        cout << "Enter a complex number (q to quit):\n";
    }
    cout << "Done!\n";
    return 0;
}

你可能感兴趣的:(2021-01-12 C++ Primer Plus 第十一章 使用类 编程练习)