C++ primer Plus(第六版)中文版 第十一章 使用类 编程练习答案
第十一章 使用类
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; }
- C++ primer Plus(第六版)中文版 编程练习答案 目录(已更新完2~12章)
- C++ Primer Plus第六版 第十一章 编程练习答案
- c++ primer plus(第6版)中文版 第十一章编程练习答案
- C++ PRIMER PLUS (第六版) 中文版 第七章编程练习答案
- C++ primer Plus(第六版)中文版 第十二章 类和动态内存分配 编程练习答案
- c++ primer plus(第6版)中文版 第九章编程练习答案
- C++ Primer Plus第六版 第四章 编程练习答案
- C++primer plus第六版课后编程练习答案4.4
- C++primer plus第六版课后编程练习答案6.7
- C++ Primer Plus第六版 第八章 编程练习答案
- C++primer plus第六版课后编程练习答案3.5
- C++primer plus第六版课后编程练习答案12.5与12.6
- c++ primer plus(第6版)中文版 第六章编程练习答案
- C++primer plus第六版课后编程练习答案7.5
- C++primer plus第六版课后编程练习答案9.1
- C++primer plus第六版课后编程练习答案7.4
- C++ Primer Plus第六版 第十三章 编程练习答案
- C++primer plus第六版课后编程练习答案12.2
- C++primer plus第六版课后编程练习答案12.4
- C++primer plus第六版课后编程练习答案2.2