您的位置:首页 > 编程语言 > C语言/C++

C++ primer Plus(第六版)中文版 第十一章 使用类 编程练习答案

2019-01-15 19:58 666 查看

第十一章 使用类
1. 修改程序清单11.15, 使之将一系列连续的随机漫步者位置写入文件中。对于每个位置,用步号进行标示。
   另外,让该程序将初始条件(目标距离和步长)以结果小结写入到该文件中。该文件的内容与下面类似:

   Target Distance: 100, Step Size: 20
    0: (x,y) = (0, 0)
    1: (x,y) = (-11.4715, 16.383)
    2: (x,y) = (-8.68807, -3.42232)
    ...
    26: (x,y) = (42.2919, -78.2594)
    27: (x,y) = (58.6749, -89.7309)
    After 27 steps, the subject has the following location:
    (x,y) = (58.6749, -89.7309)
    or
    (m,a) = (107.212, -56.8194)
    Average outward distance per step = 3.97081

书中随机漫步程序如下:

[code]// vect.h -- Vector class with <<, mode state
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
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
[code]// vect.cpp -- methods for the Vector class
#include <cmath>
#include "vect.h"   // includes <iostream>
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
    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
[code]// randwalk.cpp -- using the Vector class   (程序清单11.5)
// compile with the vect.cpp file
#include <iostream>
#include <cstdlib>      // rand(), srand() prototypes
#include <ctime>        // 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)
        {
            direction = rand() % 360;
            step.reset(dstep, direction, 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; 
}

//程序清单11.5修改后如下:

[code]// randwalk.cpp -- using the Vector class
// compile with the vect.cpp file
#include <iostream>
#include <cstdlib>      // rand(), srand() prototypes
#include <ctime>        // time() prototype
#include <fstream>                                         //修改时添加
#include "vect.h"
int main()
{
    using namespace std;
    using VECTOR::Vector;
    ofstream fout;                                         //修改时添加
    fout.open("thewalk.txt");                              //修改时添加
    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;
        
        //修改时添加
        fout << "Target Distance: " << target << ", Step Size: " << dstep << endl;
        
        while (result.magval() < target)
        {
            direction = rand() % 360;
            step.reset(dstep, direction, Vector::POL);
            result = result + step;
            
            fout << steps << ": (x,y) = " << result << endl;   //修改时添加

            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;
            
        //修改时添加    
        fout << "After " << steps << " steps, the subject "
            "has the following location:\n";
        result.rect_mode();
        fout << result << endl;
        result.polar_mode();
        fout << " or\n" << result << endl;
        fout << "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";

    return 0; 
}

2. 对Vector类的头文件(程序清单11.13) 和实现文件(程序清单11.14 进行修改),
使其不再存储矢量的长度和角度,而是在magval()和angval()被调用时计算它们
应保留公有接口不变(公有方法及参数不变),但对私有部分(包括一些私有方法)和方法实现进行修改。
然后,使用程序清单11.15 对修改后的版本进行测试,结果应该与以前相同,因为Vector类的公有接口与原来相同。

修改后:

[code]程序清单11.13 如下:
// vect.h -- Vector class with <<, mode state
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
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
       void set_x(double mag, double ang);       //通过用户输入的mag和ang求x
       void set_y(double mag, double ang);       //通过用户输入的mag和ang求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;   // report magnitude            //有修改,直接返回计算值
        double angval() const;   // 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
[code]程序清单11.14 如下:
// vect.cpp -- methods for the Vector class
#include <cmath>
#include "vect.h"   // includes <iostream>
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::magval() const
    {
        return sqrt(x * x + y * y);
    }

    double Vector::angval() 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(double mag, double ang)
    {
        x = mag * cos(ang);
    }

    // set y from polar coordinate
    void Vector::set_y(double mag, double ang)
    {
        y = mag * sin(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)
        {
             set_x(n1, n2/Rad_to_deg);
             set_y(n1, n2/Rad_to_deg);
        }
        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;
        }
        else if (form == POL)
        {
             set_x(n1, n2/Rad_to_deg);
             set_y(n1, n2/Rad_to_deg);
        }
        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
[code]//程序清单11.5(未修改) 如下:
// randwalk.cpp -- using the Vector class
// compile with the vect.cpp file
#include <iostream>
#include <cstdlib>      // rand(), srand() prototypes
#include <ctime>        // 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)
        {
            direction = rand() % 360;
            step.reset(dstep, direction, 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是用户输入的整数),而不是报告每次的结果
修改后

[code]//程序清单11.5 如下:
// randwalk.cpp -- using the Vector class
// compile with the vect.cpp file
#include <iostream>
#include <cstdlib>      // rand(), srand() prototypes
#include <ctime>        // 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;
    
    
    unsigned long maxstep;
    unsigned long minstep;
    unsigned long sumstep = 0;
    double averagestep;
    int i = 0;
    
    
    cout << "Enter target distance (q to quit): ";
    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";
        
        if(i == 0)
        {
            maxstep = steps;
            minstep = steps;            
        }
        i++;
        
        if (maxstep < steps)
            maxstep = steps;
        if (minstep > steps)
            minstep = steps;        
        
        sumstep += steps;
        averagestep = sumstep/i;
        
        cout << "Now, maxstep is " << maxstep << endl;
        cout << "Now, minstep is " << minstep << endl;
        cout << "Now, averagestep is " << averagestep << endl;

        // 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";

    return 0; 
}

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

程序清单11.10、 程序清单11.11 和程序清单11.12原程序:

[code]// mytime3.h -- Time class with friends
#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 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; }   // inline definition
friend std::ostream & operator<<(std::ostream & os, const Time & t);

};
#endif
[code]// mytime3.cpp  -- implementing Time methods
#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 Time::operator+(const Time & t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}

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

Time Time::operator*(double mult) const
{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;
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;
}

 

[code]//usetime3.cpp -- using the fourth draft of the Time class
// compile usetime3.cpp and mytime3.cpp together
#include <iostream>
#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* 1.17;  // member operator*()
cout << "Aida * 1.17: " << temp << endl;
cout << "10.0 * Tosca: " << 10.0 * tosca << endl;
// std::cin.get();
return 0;
}

修改后:

[code]// mytime3.h -- Time class with friends
#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);
    friend Time operator+(const Time & s, const Time & t);
    friend Time operator-(const Time & s, const Time & t);
    friend Time operator*(const Time & s, double n);
    friend Time operator*(double m, const Time & t)
        { return t * m; }   // inline definition
    friend std::ostream & operator<<(std::ostream & os, const Time & t);

};
#endif
[code]// mytime3.cpp  -- implementing Time methods
#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 & s, const Time & t)
{
    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*(const Time & s, double mult)
{
    Time result;
    long totalminutes = s.hours * mult * 60 + s.minutes * mult;
    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; 
}

 

[code]//usetime3.cpp -- using the fourth draft of the Time class
// compile usetime3.cpp and mytime3.cpp together
#include <iostream>
#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* 1.17;  // member operator*()
    cout << "Aida * 1.17: " << temp << endl;
    cout << "10.0 * Tosca: " << 10.0 * tosca << endl;
    // std::cin.get();
    return 0; 
}

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

程序清单11.16 和程序清单11.17原程序:

[code]// stonewt.h -- definition for the Stonewt class
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
enum {Lbs_per_stn = 14};      // pounds per stone
int stone;                    // whole stones
double pds_left;              // fractional pounds
double pounds;                // entire weight in pounds
public:
Stonewt(double lbs);          // constructor for double pounds
Stonewt(int stn, double lbs); // constructor for stone, lbs
Stonewt();                    // default constructor
~Stonewt();
void show_lbs() const;        // show weight in pounds format
void show_stn() const;        // show weight in stone format
};
#endif
[code]// stonewt.cpp -- Stonewt methods
#include <iostream>
using std::cout;
#include "stonewt.h"

// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{
stone = int (lbs) / Lbs_per_stn;    // integer division
pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
}

// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds =  stn * Lbs_per_stn +lbs;
}

Stonewt::Stonewt()          // default constructor, wt = 0
{
stone = pounds = pds_left = 0;
}

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

// show weight in stones
void Stonewt::show_stn() const
{
cout << stone << " stone, " << pds_left << " pounds\n";
}

// show weight in pounds
void Stonewt::show_lbs() const
{
cout << pounds << " pounds\n";
}

修改后:

[code]// stonewt.h -- definition for the Stonewt class
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
    enum Mode{STO, POU, FLO};
    Mode model;
    enum {Lbs_per_stn = 14};      // pounds per stone   
    //浮点磅格式(多少stone, 多少pounds) 
    int stone;                    // whole stones               
    double pds_left;              // fractional pounds        
    //整数磅格式(多少pounds)
    double pounds;                // entire weight in pounds     
public:
    Stonewt(double lbs);          // constructor for double pounds
    Stonewt(int stn, double lbs); // constructor for stone, lbs
    Stonewt();                    // default constructor
    ~Stonewt();
    
    Stonewt operator+(const Stonewt & s) const;
    Stonewt operator-(const Stonewt & s) const;
    Stonewt operator*(double n) const;
    
    void set_model_STO();
    void set_model_POU();
    void set_model_FLO();
    
    friend Stonewt operator*(double n, const Stonewt & s) {return s * n;}
    friend std::ostream & operator<<(std::ostream & os, const Stonewt & s);

};
#endif
[code]// stonewt.cpp -- Stonewt methods
#include <iostream>
#include "stonewt.h"
// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{
    stone = int (lbs) / Lbs_per_stn;    // integer division
    pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
    pounds = lbs;
    model = POU;
}

// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs)
{
    stone = stn;
    pds_left = lbs;
    pounds =  stn * Lbs_per_stn +lbs;
    model = FLO;
}

Stonewt::Stonewt()          // default constructor, wt = 0
{
    stone = pounds = pds_left = 0;
    model = STO;
}

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

void Stonewt::set_model_STO()
{
    model = STO;
}

void Stonewt::set_model_POU()
{
    model = POU;
}

void Stonewt::set_model_FLO()
{
    model = FLO;
}

Stonewt Stonewt::operator+(const Stonewt & s) const
{
    Stonewt temp;
    temp.pounds = pounds + s.pounds;
    temp.stone = temp.pounds / Lbs_per_stn;
    temp.pds_left=int(temp.pounds)%Lbs_per_stn + temp.pounds - int(temp.pounds);
    return temp;    
}

Stonewt Stonewt::operator-(const Stonewt & s) const
{
    Stonewt temp;
    temp.pounds = pounds - s.pounds;
    temp.stone = temp.pounds / Lbs_per_stn;
    temp.pds_left=int(temp.pounds)%Lbs_per_stn + temp.pounds - int(temp.pounds);
    return temp;    
}

Stonewt Stonewt::operator*(double n) const
{
    Stonewt temp;
    temp.pounds = pounds * n;
    temp.stone = temp.pounds / Lbs_per_stn;
    temp.pds_left=int(temp.pounds)%Lbs_per_stn + temp.pounds - int(temp.pounds);
    return temp;    
}

std::ostream & operator<<(std::ostream & os, const Stonewt & s)
{
    if (s.model == Stonewt::STO)
    {
        double st = s.stone + s.pds_left / Stonewt::Lbs_per_stn;
        os << st << " stone\n";
    }
    if (s.model == Stonewt::POU)
        os << s.pounds << " pounds\n";
    if (s.model == Stonewt::FLO)
        os << s.stone << " stone, " << s.pds_left << " pounds\n";
    return os;
}
[code]//usestonewt.cpp
#include <iostream>
#include "stonewt.h"

using namespace std;

int main()
{
    Stonewt one;                //使用默认构造函数
    Stonewt two(187.23);        //使用接受一个double值的构造函数
    Stonewt three(35, 0.26);    //使用接受两个值的构造函数
    Stonewt four = 190.36;      //使用接受一个double值的构造函数
    
    cout << "Show one:\n";
    cout << one;
    one.set_model_POU();
    cout << one;
    one.set_model_FLO();
    cout << one;    
    one.set_model_STO();
    cout << one;
    
    cout << "Show two:\n";
    cout << two;
    two.set_model_FLO();
    cout << two;    
    two.set_model_STO();
    cout << two;
    two.set_model_POU();
    cout << two;

    cout << "Show three:\n";
    cout << three;
    three.set_model_POU();
    cout << three;
    three.set_model_STO();
    cout << three;
    three.set_model_FLO();
    cout << three;   

    cout << "Show four:\n";
    cout << four;
    four.set_model_FLO();
    cout << four;    
    four.set_model_STO();
    cout << four;
    four.set_model_POU();
    cout << four;

    Stonewt sum_two_three = two + three;
    Stonewt minus_three_four = three - four;
    Stonewt mult_two = two * 2;
    Stonewt mult_three = 3 * three;
    
    cout << "Show sum_two_three:\n";
    cout << sum_two_three;
    cout << "Show minus_three_four:\n";
    cout << minus_three_four;
    cout << "Show mult_two:\n";
    cout << mult_two;
    cout << "Show mult_three:\n";
    cout << mult_three;
    
    return 0;
}

6. 重新编写Stonewt类(程序清单11.16 和程序清单11.17 ),重载全部6个关系运算符。
   运算符对pounds成员进行比较,并返回一个bool值。
   编写一个程序,它声明一个包含6个Stonewt对象的数组,并在数组声明中初始化前3个对象。
   然后使用循环来读取用于设置剩余3个数组元素的值。
   接着报告最小的元素、最大的元素以及大于等于11英石的元素的数量
   (最简单的方法是创建一个Stonewt对象,并将其初始化为11英石,然后将其同其他对象进行比较)。

[code]// stonewt.h -- definition for the Stonewt class
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
    enum {Lbs_per_stn = 14};      // pounds per stone
    int stone;                    // whole stones
    double pds_left;              // fractional pounds
    double pounds;                // entire weight in pounds
public:
    Stonewt(double lbs);          // constructor for double pounds
    Stonewt(int stn, double lbs); // constructor for stone, lbs
    Stonewt();                    // default constructor
    ~Stonewt();
    
    bool operator<(const Stonewt & s);
    bool operator<=(const Stonewt & s);
    bool operator>(const Stonewt & s);
    bool operator>=(const Stonewt & s);
    bool operator==(const Stonewt & s);
    bool operator!=(const Stonewt & s);

    void show_lbs() const;        // show weight in pounds format
    void show_stn() const;        // show weight in stone format
};
#endif
[code]// stonewt.cpp -- Stonewt methods
#include <iostream>
using std::cout;
#include "stonewt.h"

// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{
    stone = int (lbs) / Lbs_per_stn;    // integer division
    pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
    pounds = lbs;
}

// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs)
{
    stone = stn;
    pds_left = lbs;
    pounds =  stn * Lbs_per_stn +lbs;
}

Stonewt::Stonewt()          // default constructor, wt = 0
{
    stone = pounds = pds_left = 0;
}

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

bool Stonewt::operator<(const Stonewt & s) const
{
    if (pounds < s.pounds)
        return true;
    else
        return false;
}

bool Stonewt::operator<=(const Stonewt & s) const
{
    if (pounds <= s.pounds)
        return true;
    else
        return false;
}

bool Stonewt::operator>(const Stonewt & s) const
{
    if (pounds > s.pounds)
        return true;
    else
        return false;
}

bool Stonewt::operator>=(const Stonewt & s) const
{
    if (pounds >= s.pounds)
        return true;
    else
        return false;
}

bool Stonewt::operator==(const Stonewt & s) const
{
    if (pounds == s.pounds)
        return true;
    else
        return false;
}

bool Stonewt::operator!=(const Stonewt & s) const
{
    if (pounds != s.pounds)
        return true;
    else
        return false;
}

// show weight in stones
void Stonewt::show_stn() const
{
    cout << stone << " stone, " << pds_left << " pounds\n";
}

// show weight in pounds
void Stonewt::show_lbs() const
{
    cout << pounds << " pounds\n";
}
[code]//usestonewt.cpp
#include <iostream>
#include "stonewt.h"

using namespace std;

int main()
{
    Stonewt array[6] = {123.56, Stonewt(12, 0.35), Stonewt(15, 0)};
    double input;
    Stonewt const11 = Stonewt(11, 0);
    Stonewt max = array[0];
    Stonewt min = array[0];
    int num = 0;
    
    for (int i = 3; i < 6; i++)
    {
        cout << "请输入第" << i+1 << "个元素的pounds值:" ;
        cin >> input;
        array[i] = Stonewt(input);
        cin.get();
    }
    
    for (int i = 0; i < 6; i++)
    {
        if (max < array[i])
            max = array[i];
        if (min > array[i])
            min = array[i];
        if (array[i] > const11)
            num++;
    }
    
    for (int i = 0; i < 6; i++)
    {
        cout << "第" << i+1 << "个:\n";
        array[i].show_stn();    
        array[i].show_lbs();
        cout << endl;
    }
    
    cout << "最大:\n";
    max.show_stn();
    max.show_lbs();
    cout << endl;
    
    cout << "最小:\n";  
    min.show_stn();    
    min.show_lbs();
    cout << endl;
    
    cout << "超过11英石的有:" << num << "个\n";
    
    return 0;
}

7. 复数由两个部分组成:实数部分和虚数部分。复数的一种书写方式是:(3.0, 4.0),其中,3.0 是实数部分。4.0 是虚数部分。
   假设a=(A,Bi),c=(C,Di),则下面是一些复数运算
   ·加法: a+c=(A+C,(B+D)i)
   ·减法: a-c=(A+C,(B+D)i)
   ·乘法: a*c=(A*C-B*D,(A*D+B*C)i)
   ·数乘: x*c=(x*C,x*Di)
   ·共轭: ~a=(A,-Bi)
   请定义一个复数类,以便下面的程序可以使用它来获得正确的结果。

   #include <iostream>
    using namespace std;
    #include "complex0.h"  // to avoid confusion with complex.h
    int main()
    {
        complex a(3.0, 4.0);     // initialize to (3,4i)
        complex 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;
    }
    注意,必须重载运算符<<和>>。标准C++头文件complex提供了比这个示例更广泛的复数支持,
    因此应将自定义的头文件命名为complex0.h,以免发生冲突。应尽可能使用const。
    下面是该程序的运行情况。
    Enter a complex number (q to quit):
    real: 10
    imaginary: 12
    c is (10,12i)
    complex conjugate is (10,-12i)
    a is (3,4i)
    a + c is (13,16i)
    a - c is (-7,-8i)
    a * c is (-18,76i)
    2 * c is (20,24i)
    Enter a complex number (q to quit):
    real: q
    Done!
    请注意,经过重载后,cin>>c将提示用户输入实数部分和虚数部分。

[code]//complex0.h
#ifndef COMPLEX0_H_
#define COMPLEX0_H_

class Complex0
{
private:
    double realpart;    //实部
    double imagpart;    //虚部
public:
    Complex0(double realnum = 0, double imagnum = 0);
    ~Complex0();
    Complex0 operator+(const Complex0 & c) const;
    Complex0 operator-(const Complex0 & c) const;
    Complex0 operator*(const Complex0 & c) const;

    friend Complex0 operator*(double x, const Complex0 & c);
    friend Complex0 operator~(const Complex0 & c);
    friend std::istream & operator>>(std::istream & ins, Complex0 & c);
    friend std::ostream & operator<<(std::ostream & os, const Complex0 & c);
};
#endif
[code]//complex0.cpp
#include <iostream>
#include "Complex0.h"

Complex0::Complex0(double realnum, double imagnum)
{
    realpart = realnum;
    imagpart = imagnum;
}

Complex0::~Complex0()
{
}

Complex0 Complex0::operator+(const Complex0 & c) const
{
    Complex0 temp;
    temp.realpart = realpart + c.realpart;
    temp.imagpart = imagpart + c.imagpart;
    return temp;
}

Complex0 Complex0::operator-(const Complex0 & c) const
{
    Complex0 temp;
    temp.realpart = realpart - c.realpart;
    temp.imagpart = imagpart - c.imagpart;
    return temp;
}

Complex0 Complex0::operator*(const Complex0 & c) const
{
    Complex0 temp;
    temp.realpart = realpart * c.realpart - imagpart * c.imagpart;
    temp.imagpart = realpart * c.imagpart + imagpart * c.realpart;
    return temp;
}

Complex0 operator*(double x, const Complex0 & c)
{
    Complex0 temp;
    temp.realpart = x * c.realpart;
    temp.imagpart = x * c.imagpart;
    return temp;
}
Complex0 operator~(const Complex0 & c)
{
    Complex0 temp;
    temp.realpart = c.realpart;
    temp.imagpart = -1 * c.imagpart;
    return temp;
}

std::istream & operator>>(std::istream & ins, Complex0 & c)
{
    std::cout << "real: ";
    if (!(ins >> c.realpart))
        return ins;
    std::cout << "imaginary: ";
    ins >> c.imagpart;
    return ins;
}

std::ostream & operator<<(std::ostream & os, const Complex0 & c)
{
    os << "(" << c.realpart << ", " << c.imagpart << "i)";
    return os;
}
[code]//usecomplex0.cpp
#include <iostream>
using namespace std;
#include "complex0.h"  // to avoid confusion with complex.h

int main()
{
    Complex0 a(3.0, 4.0);     // initialize to (3,4i)
    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;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: