// vector1.h -- Vector class with <<, mode state
#ifndef __VECTOR1_H__
#define __VECTOR1_H__
#include <iostream>
namespace VECTOR1
{
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 VECTOR1
#endif /* __VECTOR1_H__ */
// vector1.cpp -- methods for the Vector class#include <cmath>#include "vector1.h" // include <iostream>using std::sqrt;using std::sin;using std::cos;using std::atan;using std::atan2;using std::cout;namespace VECTOR1{ // compute degrees in one radian const double Rad_to_deg = 45.0 / atan(1.0); // shoule 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 (0.0 == x && 0.0 == y) 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 (RECT == form) { x = n1; y = n2; set_mag(); set_ang(); } else if (POL == form) { mag = n1; ang = n2; 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 (RECT == form) { x = n1; y = n2; set_mag(); set_ang(); } else if (POL == form) { mag = n1; ang = n2; 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 to Vectors Vector Vector::operator+(const Vector & b) const { // 调用构造函数会自动生成一个临时对象来存放这些值 return Vector(x + b.x, y + b.y); // 等价 { /* Vector sum; sum.x = x + b.x; sum.y = y + b.y; sum.set_ang(sum.x, sum.y); sum.set_ang(sum.x, sum.y); return sum; // version duplicates needlessly */ //} } // 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) { // 因为该函数是友元函数,不属于类成员,所以使用RECT和POL // 需要加Vector::来访问类的枚举成员 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 VECTOR1
/*********************************** 2017年11月13日16:11:48 Athor:xiyuan255 Course:C++ Contain:randwalk1.cpp vactor1.h vactor1.cpp Reference: C++ Primer plus 说明:C++ Primer plus第十一章的第一题练习题 【 P423 】*************************************/// randwalk1.cpp -- using the Vector class// compile with the vector1.cpp file#include <iostream>#include <cstdlib> // rand(), srand() prototypes#include <ctime> // time() prototype#include <fstream> // ofstream and ifstream#include "vector1.h"int main(){ using namespace std; using VECTOR1::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; ofstream fout; fout.open("reault.txt"); if (!fout.is_open()) { cout << "File reault.txt cannot open.\n"; exit(-1); } cout << "Enter target distance (q to quit): "; while (cin >> target) { cout << "Enter step length: "; if (!(cin >> dstep)) break; fout << "Target Distance: " << target << ", Step: " << dstep << endl; while (result.magVal() < target) { fout << steps << ": " << result << endl; direction = rand() % 360; step.reset(dstep, direction, Vector::POL); result = result + step; steps++; } fout << "After " << steps << " steps, the subject " "has the following location:\n"; fout << result << endl; result.polar_mode(); fout << " or\n" << result << endl; fout << "Average outward distance per step = " << result.angVal() / steps << endl; steps = 0; result.reset(0.0, 0.0); cout << "Enter target distance (q to quit): "; } cout << "check reault.txt file -Bye!\n"; /* 当cin >> xxx 返回错误时,会堵塞输入序列,则需要 * 使用cin.clear() 重新打开输入序列 */ cin.clear(); while (cin.get() != '\n') continue; return 0;}/**输出结果: Enter target distance (q to quit): 100 Enter step length: 20 Enter target distance (q to quit): q check reault.txt file -Bye!result.txt文件的内容是: Target Distance: 100, Step: 20 0: (x, y) = (0, 0) 1: (x, y) = (-3.95627, 19.6048) 2: (x, y) = (-8.94766, 38.9719) 3: (x, y) = (-6.73931, 19.0942) 4: (x, y) = (-24.4987, 9.89616) 5: (x, y) = (-32.1727, -8.57301) 6: (x, y) = (-12.2854, -6.45266) 7: (x, y) = (-10.2537, 13.4439) 8: (x, y) = (-26.4339, 1.68797) 9: (x, y) = (-43.8565, -8.13298) 10: (x, y) = (-51.5305, -26.6022) 11: (x, y) = (-71.1526, -30.4716) 12: (x, y) = (-52.7176, -38.2273) 13: (x, y) = (-70.3113, -47.7383) 14: (x, y) = (-61.3504, -29.8581) 15: (x, y) = (-44.1947, -19.578) 16: (x, y) = (-25.2571, -26.0098) 17: (x, y) = (-30.2485, -6.64271) 18: (x, y) = (-12.3288, -15.5244) 19: (x, y) = (-10.8255, -35.4678) 20: (x, y) = (8.99858, -38.1149) 21: (x, y) = (-10.9889, -37.4075) 22: (x, y) = (8.9829, -36.3458) 23: (x, y) = (28.9328, -34.9308) 24: (x, y) = (26.5486, -15.0734) 25: (x, y) = (6.56816, -15.9583) 26: (x, y) = (-4.97189, 0.376584) 27: (x, y) = (-6.47461, -19.5669) 28: (x, y) = (-25.8196, -14.4904) 29: (x, y) = (-41.1275, -27.3616) 30: (x, y) = (-53.9304, -42.7267) 31: (x, y) = (-34.6784, -37.308) 32: (x, y) = (-51.8345, -27.0285) 33: (x, y) = (-62.6411, -10.1994) 34: (x, y) = (-76.499, 4.22138) 35: (x, y) = (-56.9865, 8.61047) 36: (x, y) = (-74.6641, 17.9648) 37: (x, y) = (-84.0966, 0.328869) 38: (x, y) = (-88.5714, -19.1641) 39: (x, y) = (-70.206, -11.245) 40: (x, y) = (-59.5488, -28.1691) 41: (x, y) = (-39.8612, -31.6901) 42: (x, y) = (-53.1999, -16.7878) 43: (x, y) = (-55.7592, -36.6234) 44: (x, y) = (-35.7662, -37.1538) 45: (x, y) = (-45.5095, -54.62) 46: (x, y) = (-25.5095, -54.62) 47: (x, y) = (-42.7555, -64.7479) 48: (x, y) = (-23.2826, -69.3089) 49: (x, y) = (-31.9261, -51.2731) 50: (x, y) = (-11.9543, -50.2115) 51: (x, y) = (-27.8171, -38.0306) 52: (x, y) = (-38.324, -21.0128) 53: (x, y) = (-18.8923, -16.279) 54: (x, y) = (-14.7627, -35.848) 55: (x, y) = (-24.8136, -53.1391) 56: (x, y) = (-44.8065, -53.6701) 57: (x, y) = (-25.0066, -56.4919) 58: (x, y) = (-7.58362, -66.3123) 59: (x, y) = (0.253528, -47.9118) 60: (x, y) = (20.0535, -50.7336) 61: (x, y) = (0.754301, -55.9817) 62: (x, y) = (-3.37475, -75.5508) 63: (x, y) = (2.29849, -94.7293) 64: (x, y) = (-15.6991, -86.0065) After 65 steps, the subject has the following location: (x, y) = (-31.6687, -98.047) or (m, a) = (103.035, -107.9) Average outward distance per step = -0.0289725*/
// stonewt2.cpp -- Stonewt methods#include <iostream>using std::cout;#include "stonewt2.h"// constructor Stonewt object from double valueStonewt::Stonewt(double lbs){ stone = int (lbs) / Lbs_per_stn; // integer division pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs); pounds = lbs;}// constructor Stonewt object from stone, double valuesStonewt::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 {}void Stonewt::setState(){ using std::cout; using std::cin; int mode = 0; cout << "Enter object fromat:\n" << " 1) stone format 2) integer pounds format\n" << " 3) double pounds format 4) unkown \n"; cin >> mode; if (1 == mode) { state = STON_FORMAT; } else if (2 == mode) { state = INT_POUN_FORMAT; } else if (3 == mode) { state = DOU_POUN_FORMAT; } else { cout << "Not the this object format!\n"; }}void Stonewt::resetStonewt(double lbs){ stone = int (lbs) / Lbs_per_stn; // integer division pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs); pounds = lbs;}void Stonewt::resetStonewt(int stn, double lbs){ stone = stn; pds_left = lbs; pounds = stn * Lbs_per_stn + lbs;}// overload operatorStonewt Stonewt::operator+(const Stonewt & swt) const{ return Stonewt(pounds + swt.pounds);}Stonewt Stonewt::operator-(const Stonewt & swt) const{ return Stonewt(pounds - swt.pounds);}Stonewt Stonewt::operator*(double m) const{ return Stonewt(pounds * m);}Stonewt Stonewt::operator/(const Stonewt & swt) const{ return Stonewt(pounds / swt.pounds);}std::ostream & operator<<(std::ostream & os, const Stonewt & swt){ if (swt.state == Stonewt::STON_FORMAT) { os << swt.stone << " stone, " << swt.pds_left << " pounds "; } else if (swt.state == Stonewt::INT_POUN_FORMAT) { os << int(swt.pounds + 0.5) << " pounds "; } else if (swt.state == Stonewt::DOU_POUN_FORMAT) { os << swt.pounds << " pounds "; } else { os << "Output error not the this object!"; } return os;}
/*********************************** 2017年11月14日13:10:48 Athor:xiyuan255 Course:C++ Contain:usestone.cpp stonewt2.h stonewt2.cpp Reference: C++ Primer plus 说明:C++ Primer plus第十一章的第五题练习题 【 P423 】*************************************/// usestone.cpp -- user-defined conversions// compile with stonewt2.cpp#include <iostream>using std::cout;using std::endl;#include "stonewt2.h"int main(){ // 只有有一个参数的构造函数才可如此调用 Stonewt incognito = 275; // uses constructor to initialize // or Stonewt incognito = Stonewt(275); // 显式调用构造函数 // or Stonewt incognito(275); // 隐式调用构造函数 Stonewt wolfe(285.7); // same as Stonewt wolfe = 285.7; Stonewt taft(21, 8); incognito.setState(); cout << "The celebrity weighed "; cout << incognito << endl; Stonewt sum = incognito + wolfe; sum.setState(); cout << "sum = "; cout << sum << endl; Stonewt sub = wolfe - incognito; sub.setState(); cout << "sub = "; cout << sub << endl; Stonewt mult = 2 * taft; mult.setState(); cout << "mult = "; cout << mult << endl; Stonewt div = mult / taft; div.setState(); cout << "div = "; cout << div << endl; incognito.resetStonewt(255); incognito.setState(); cout << "incognito = "; cout << incognito << endl; return 0;}/**输出结果: Enter object fromat: 1) stone format 2) integer pounds format 3) double pounds format 4) unkown 2 The celebrity weighed 275 pounds Enter object fromat: 1) stone format 2) integer pounds format 3) double pounds format 4) unkown 3 sum = 560.7 pounds Enter object fromat: 1) stone format 2) integer pounds format 3) double pounds format 4) unkown 3 sub = 10.7 pounds Enter object fromat: 1) stone format 2) integer pounds format 3) double pounds format 4) unkown 1 mult = 43 stone, 2 pounds Enter object fromat: 1) stone format 2) integer pounds format 3) double pounds format 4) unkown 1 div = 0 stone, 2 pounds Enter object fromat: 1) stone format 2) integer pounds format 3) double pounds format 4) unkown 2 incognito = 255 pounds*/
// stonewt3.h -- definition for the Stonewt class#ifndef __STONEWT3_H__#define __STONEWT3_H__#include <iostream>class Stonewt{private: enum Mode_e { STON_FORMAT, INT_POUN_FORMAT, DOU_POUN_FORMAT }; static const int Lbs_per_stn = 14; // 一英石 = 14磅 Mode_e state; int stone; // whole stones (英石) double pds_left; // fractional pounds (不够1英石的磅重量) double pounds; // entire weight in pounds (磅)public: Stonewt(double lbs); // constructor for double pounds Stonewt(int stn, double lbs); // constructor for stone, lbs Stonewt(); // 默认的构造函数 ~Stonewt(); // 析构函数 void setState(); void setState(int mode); void resetStonewt(double lbs); void resetStonewt(int stn, double lbs); // conversion function // 转换函数 operator double() const; operator int() const; // overload operator // 运算符的重载函数 bool operator>(const Stonewt & swt) const; bool operator<(const Stonewt & swt) const; bool operator>=(const Stonewt & swt) const; bool operator<=(const Stonewt & swt) const; bool operator==(const Stonewt & swt) const; bool operator!=(const Stonewt & swt) const; // 友元函数 friend std::ostream & operator<<(std::ostream & os, const Stonewt & swt); friend std::istream & operator>>(std::istream & is, Stonewt & swt);};#endif /* __STONEWT3_H__ */
// stonewt3.cpp -- Stonewt methods#include <iostream>#include "stonewt3.h"// constructor Stonewt object from double valueStonewt::Stonewt(double lbs){ stone = int (lbs) / Lbs_per_stn; // integer division pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs); pounds = lbs;}// constructor Stonewt object from stone, double valuesStonewt::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 {}void Stonewt::setState(){ using std::cout; using std::cin; int mode = 0; cout << "Enter object fromat:\n" << " 1) stone format 2) integer pounds format\n" << " 3) double pounds format 4) unkown \n"; cin >> mode; if (1 == mode) { state = STON_FORMAT; } else if (2 == mode) { state = INT_POUN_FORMAT; } else if (3 == mode) { state = DOU_POUN_FORMAT; } else { cout << "Not the this object format!\n"; }}void Stonewt::setState(int mode){ using std::cout; if (1 == mode) { state = STON_FORMAT; } else if (2 == mode) { state = INT_POUN_FORMAT; } else if (3 == mode) { state = DOU_POUN_FORMAT; } else { cout << "Not the this object format!\n"; }}void Stonewt::resetStonewt(double lbs){ stone = int (lbs) / Lbs_per_stn; // integer division pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs); pounds = lbs;}void Stonewt::resetStonewt(int stn, double lbs){ stone = stn; pds_left = lbs; pounds = stn * Lbs_per_stn + lbs;}Stonewt::operator double() const{ return pounds;}Stonewt::operator int() const{ return int (pounds + 0.5);}// overload operatorbool Stonewt::operator>(const Stonewt & swt) const{ return (pounds > swt.pounds);}bool Stonewt::operator<(const Stonewt & swt) const{ return (pounds < swt.pounds);}bool Stonewt::operator>=(const Stonewt & swt) const{ //return (pounds >= swt.pounds); if (pounds >= swt.pounds) return true; else return false;}bool Stonewt::operator<=(const Stonewt & swt) const{ return (pounds <= swt.pounds);}bool Stonewt::operator==(const Stonewt & swt) const{ return (pounds == swt.pounds);}bool Stonewt::operator!=(const Stonewt & swt) const{ return (pounds != swt.pounds);}std::ostream & operator<<(std::ostream & os, const Stonewt & swt){ if (swt.state == Stonewt::STON_FORMAT) { os << swt.stone << " stone, " << swt.pds_left << " pounds "; } else if (swt.state == Stonewt::INT_POUN_FORMAT) { os << (int)swt.pounds << " pounds "; } else if (swt.state == Stonewt::DOU_POUN_FORMAT) { os << swt.pounds << " pounds "; } else { os << "Output error not the this object!"; } return os;}std::istream & operator>>(std::istream & is, Stonewt & swt){ double temp; is >> temp; swt.resetStonewt(temp); return is;}
/*********************************** 2017年11月14日17:07:39 Athor:xiyuan255 Course:C++ Contain:usestone3.cpp stonewt3.h stonewt3.cpp Reference: C++ Primer plus 说明:C++ Primer plus第十一章的第六题练习题 【 P423 】*************************************/// usestone3.cpp -- user-defined conversions// compile with stonewt3.cpp#include <iostream>#include "stonewt3.h"int main(){ using std::cin; using std::cout; using std::endl; Stonewt temp(11, 0); Stonewt ston[6] = { 10, 11, 12 }; cout << "enter last third element value: \n"; for (int i = 3; i < 6; i++) { cout << " #" << i << " element value:"; if (!(cin >> ston[i])) break; } cout << "Set array stone display format:\n" << " 1) stone format 2) integer pounds format\n" << " 3) double pounds format 4) unkown \n"; int mode; cin >> mode; for (int i = 0; i < 6; i++) { ston[i].setState(mode); } temp.setState(mode); for (int i = 0; i < 6; i++) { cout << "#" << (i + 1) << ": " << ston[i] << endl; } cout << "more than 11 stone(154 pounds) for element: " << endl; Stonewt max = ston[0], min = ston[0]; for (int i = 0; i < 6; i++){ if (ston[i] < min) min = ston[i]; if (ston[i] > max) max = ston[i]; if (ston[i] >= temp) cout << ston[i]; } cout << "\nmaximum element:" << max; cout << ", minimum element:" << min << endl; return 0;}/**输出结果: enter last third element value: #3 element value:153 #4 element value:154 #5 element value:256 Set array stone display format: 1) stone format 2) integer pounds format 3) double pounds format 4) unkown 2 #1: 10 pounds #2: 11 pounds #3: 12 pounds #4: 153 pounds #5: 154 pounds #6: 256 pounds more than 11 stone(154 pounds) for element: 154 pounds 256 pounds maximum element:256 pounds , minimum element:10 pounds*/
// complex0.h -- class Complex0 declaration#ifndef __COMPLEX0_H__#define __COMPLEX0_H__#include <iostream>class complex{private: double real; double imaginary;public: complex(); // 构造函数 complex(double re, double im); ~complex(); // 析构函数 // overload operator complex operator+(const complex & c) const; complex operator-(const complex & c) const; complex operator*(const complex & c) const; complex operator~() const; friend complex operator*(double x, const complex & c); friend std::ostream & operator<<(std::ostream & os, const complex & c); friend std::istream & operator>>(std::istream & is, complex & c);};#endif /* __COMPLEX0_H__ */
// complex0.cpp -- class complex function definition#include "complex0.h"// constructor functioncomplex::complex(){ real = imaginary = 0.0;}complex::complex(double re, double im){ real = re; imaginary = im;}complex::~complex(){}complex complex::operator+(const complex & c) const{ return complex(real + c.real, imaginary + c.imaginary);}complex complex::operator-(const complex & c) const{ return complex(real - c.real, imaginary - c.imaginary);}complex complex::operator*(const complex & c) const{ return complex(real * c.real - imaginary * c.imaginary, real * c.imaginary + imaginary * c.real);}complex complex::operator~() const{ return complex(real, -imaginary);}// friend functioncomplex operator*(double x, const complex & c){ return complex(x * c.real, x * c.imaginary);}std::ostream & operator<<(std::ostream & os, const complex & c){ os << "(" << c.real << ", " << c.imaginary << "i) "; return os;}std::istream & operator>>(std::istream & is, complex & c){ using std::cout; cout << "real: "; if (!(is >> c.real)) return is; cout << "imaginary: "; is >> c.imaginary; return is;}
/*********************************** 2017年11月15日10:40:18 Athor:xiyuan255 Course:C++ Contain:usecomplex0.cpp complex0.h complex0.cpp Reference: C++ Primer plus 说明:C++ Primer plus第十一章的第七题练习题 【 P423 】 注:运算符的重载函数,当是局部变量作为返回值,不要用引用返回; 如:complex operator+(const complex & c) const 函数的返回值不要写成complex & 类型,因为它在本程序返回的是 complex(real + c.real, imaginary + c.imaginary)对象,如果是引用 类型的返回值,则是返回complex(real + c.real, imaginary + c.imaginary) 对象的别名,而这个对象在搞函数执行完毕后会被释放,则在主函数中如果访问 了该对象别名就会出现访问已经被释放的内存空间。 如果是非引用型返回值,则不会有这个问题,它会通过return将该对象复制到该 函数的返回类型对应的临时空间中,然后在主函数把该临时对象复制该需要的对象。*************************************/// usecomplex0.cpp -- use class complex0 of function// compile with complex0.cpp#include <iostream>using namespace std;#include "complex0.h" // to avoid confusion with complex.hint main(){ complex a(3.0, 4.0); // initialie to (3, 4i) complex c; cout << "Enter a complex number (q to quit):\n"; while (cin >> c) { cout << "c is " << c << endl; 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;}/**输出结果: 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!*/
// vector2.h -- Vector class with <<, mode state#ifndef __VECTOR2_H__#define __VECTOR2_H__#include <iostream>namespace VECTOR2{ 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 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 sqrt(x * x + y * y); } // report magnitude double angVal() const { double ang; if (0.0 == x && 0.0 == y) ang = 0.0; else ang = atan2(y, x); 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 VECTOR2 #endif /* __VECTOR2_H__ */
// vector2.cpp -- methods for the Vector class#include <cmath>#include "vector2.h" // include <iostream>using std::sqrt;using std::sin;using std::cos;using std::atan;using std::atan2;using std::cout;namespace VECTOR2{ // compute degrees in one radian const double Rad_to_deg = 45.0 / atan(1.0); // shoule be about 57.2957795130823 // 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 (RECT == form) { x = n1; y = n2; } else if (POL == form) { x = n1 * cos(n2); y = n1 * sin(n2); } 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 (RECT == form) { x = n1; y = n2; } else if (POL == form) { x = n1 * cos(n2); y = n1 * sin(n2); } 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 to Vectors Vector Vector::operator+(const Vector & b) const { // 调用构造函数会自动生成一个临时对象来存放这些值 return Vector(x + b.x, y + b.y); // 等价 { /* Vector sum; sum.x = x + b.x; sum.y = y + b.y; sum.set_ang(sum.x, sum.y); sum.set_ang(sum.x, sum.y); return sum; // version duplicates needlessly */ //} } // 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) { // 因为该函数是友元函数,不属于类成员,所以使用RECT和POL // 需要加Vector::来访问类的枚举成员 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 VECTOR2
/*********************************** 2017年11月13日16:59:23 Athor:xiyuan255 Course:C++ Contain:randwalk2.cpp vactor2.h vactor2.cpp Reference: C++ Primer plus 说明:C++ Primer plus第十一章的第二题练习题 【 P423 】*************************************/// randwalk2.cpp -- using the Vector class// compile with the vector2.cpp file#include <iostream>#include <cstdlib> // rand(), srand() prototypes#include <ctime> // time() prototype#include "vector2.h"int main(){ using namespace std; using VECTOR2::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, 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.angVal() / steps << endl; steps = 0; result.reset(0.0, 0.0); cout << "Enter target distance (q to quit): "; } cout << "Bye!\n"; /* 当cin >> xxx 返回错误时,会堵塞输入序列,则需要 * 使用cin.clear() 重新打开输入序列 */ cin.clear(); while (cin.get() != '\n') continue; return 0;}/**输出结果: Enter target distance (q to quit): 50 Enter step length: 2 After 857 steps, the subject has the following location: (x, y) = (-50.5311, 3.03791) or (m, a) = (50.6223, 176.56) Average outward distance per step = 0.00359574 Enter target distance (q to quit): 50 Enter step length: 2 After 370 steps, the subject has the following location: (x, y) = (38.7306, -33.2692) or (m, a) = (51.0578, -40.6622) Average outward distance per step = -0.00191808 Enter target distance (q to quit): 50 Enter step length: 1 After 7595 steps, the subject has the following location: (x, y) = (8.80658, 49.2528) or (m, a) = (50.0339, 79.8624) Average outward distance per step = 0.000183524 Enter target distance (q to quit): q Bye!*/
// vector3.h -- Vector class with <<, mode state#ifndef __VECTOR3_H__#define __VECTOR3_H__#include <iostream>namespace VECTOR3{ 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 VECTOR3 #endif /* __VECTOR3_H__ */
// vector3.cpp -- methods for the Vector class#include <cmath>#include "vector3.h" // include <iostream>using std::sqrt;using std::sin;using std::cos;using std::atan;using std::atan2;using std::cout;namespace VECTOR3{ // compute degrees in one radian const double Rad_to_deg = 45.0 / atan(1.0); // shoule 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 (0.0 == x && 0.0 == y) 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 (RECT == form) { x = n1; y = n2; set_mag(); set_ang(); } else if (POL == form) { mag = n1; ang = n2; 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 (RECT == form) { x = n1; y = n2; set_mag(); set_ang(); } else if (POL == form) { mag = n1; ang = n2; 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 to Vectors Vector Vector::operator+(const Vector & b) const { // 调用构造函数会自动生成一个临时对象来存放这些值 return Vector(x + b.x, y + b.y); // 等价 { /* Vector sum; sum.x = x + b.x; sum.y = y + b.y; sum.set_ang(sum.x, sum.y); sum.set_ang(sum.x, sum.y); return sum; // version duplicates needlessly */ //} } // 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) { // 因为该函数是友元函数,不属于类成员,所以使用RECT和POL // 需要加Vector::来访问类的枚举成员 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 VECTOR3
/*********************************** 2017年11月14日09:10:25 Athor:xiyuan255 Course:C++ Contain:randwalk3.cpp vactor3.h vactor3.cpp Reference: C++ Primer plus 说明:C++ Primer plus第十一章的第三题练习题 【 P423 】*************************************/// randwalk3.cpp -- using the Vector class// compile with the vector3.cpp file#include <iostream>#include <cstdlib> // rand(), srand() prototypes#include <ctime> // time() prototype#include "vector3.h"int main(){ using namespace std; using VECTOR3::Vector; srand(time(0)); // seed random-number generator int N; double direction; Vector step; Vector result(0.0, 0.0); unsigned long steps = 0; double target; double dstep; unsigned long max_steps = 0x0000000000000000; unsigned long min_steps = 0xFFFFFFFFFFFFFFFF; unsigned long sum_steps = 0; cout << "Enter target distance (q to quit): "; while (cin >> target) { cout << "Enter step length: "; if (!(cin >> dstep)) break; cout << "Enter N number value: "; if (!(cin >> N)) break; int n = 0; while (n++ < N) { while (result.magVal() < target) { direction = rand() % 360; step.reset(dstep, direction, Vector::POL); result = result + step; steps++; } if (max_steps < steps) max_steps = steps; if (min_steps > steps) min_steps = steps; sum_steps += steps; steps = 0; result.reset(0.0, 0.0); } cout << N << " times sample steps of "<< "Maximum: " << max_steps; cout << ", Minimum: " << min_steps; cout << ", Average: " << (double)sum_steps / N << endl; cout << "Enter target distance (q to quit): "; } cout << "Bye!\n"; /* 当cin >> xxx 返回错误时,会堵塞输入序列,则需要 * 使用cin.clear() 重新打开输入序列 */ cin.clear(); while (cin.get() != '\n') continue; return 0;}/**输出结果: Enter target distance (q to quit): 100 Enter step length: 2 Enter N number value: 3 3 times sample steps of Maximum: 11656, Minimum: 1169, Average: 5158.67 Enter target distance (q to quit): q Bye!*/
// mytime4.h -- Time class before operator overloading#ifndef __MYTIME4_H__#define __MYTIME4_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 & t1, const Time & t2); friend Time operator-(const Time & t1, const Time & t2); friend Time operator*(const Time & t, double m); friend Time operator*(double m, const Time & t) { // 有元函数 return t * m; // inline definition 内联定义 (use t.operator*(m)) } friend std::ostream & operator<<(std::ostream & os, const Time & t);};#endif /* __MYTIME4_H__ */
// mytime4.cpp -- implementing Time methods#include <iostream>#include "mytime4.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 & t1, const Time & t2){ Time sum; sum.minutes = t1.minutes + t2.minutes; sum.hours = t1.hours + t2.hours + sum.minutes / 60; sum.minutes %= 60; return sum;}Time operator-(const Time & t1, const Time & t2){ Time diff; int tot1, tot2; tot1 = t2.minutes + 60 * t2.hours; tot2 = t1.minutes + 60 * t1.hours; diff.minutes = (tot2 - tot1) % 60; diff.hours = (tot2 - tot1) / 60; return diff;}Time operator*(const Time & t, double mult){ Time result; long totalminutes = t.hours * mult * 60 + t.minutes * mult; result.minutes = totalminutes % 60; result.hours = totalminutes / 60; return result;}std::ostream & operator<<(std::ostream & os, const Time & t){ os << t.hours << " hours, " << t.minutes << " minutes"; return os;}
/*********************************** 2017年11月14日09:26:15 Athor:xiyuan255 Course:C++ Contain:usetime4.cpp mytime4.h mytime4.cpp Reference: C++ Primer plus 说明:C++ Primer plus第十一章的第四题练习题 【 P423 】*************************************/// usetime4.cpp -- using the fourth draft of the Time class// compile usetime4.cpp and mytime4.cpp together#include <iostream>#include "mytime4.h"int main(){ using std::cout; using std::endl; Time aida(3, 35); Time tosca = Time(2, 48); Time temp; cout << "Aida and Tosca: \n"; // std::ostream & operator<<(cout, aida) cout << aida << "; " << tosca << endl; temp = aida + tosca; cout << "Aida + Tosca: " << temp << endl; temp = aida * 1.17; // use aida.operator*(1.17) 类的重载函数调用 cout << "aida * 1.17: " << temp << endl; // use operator*(10.0, tosca) 有元函数的调用 cout << "10.0 * Tosca: " << 10.0 * tosca << endl; return 0;}/**输出结果: Aida and Tosca: 3 hours, 35 minutes; 2 hours, 48 minutes Aida + Tosca: 6 hours, 23 minutes aida * 1.17: 4 hours, 11 minutes 10.0 * Tosca: 28 hours, 0 minutes*/
// stonewt2.h -- definition for the Stonewt class#ifndef __STONEWT2_H__#define __STONEWT2_H__#include <iostream>class Stonewt{private: enum Mode_e { STON_FORMAT, INT_POUN_FORMAT, DOU_POUN_FORMAT }; /* 一英石 = 14磅 */ enum { Lbs_per_stn = 14 }; // pounds per stone // or static const int Lbs_per_stn = 14; Mode_e state; int stone; // whole stones (英石) double pds_left; // fractional pounds (不够1英石的磅重量) double pounds; // entire weight in pounds (磅)public: Stonewt(double lbs); // constructor for double pounds Stonewt(int stn, double lbs); // constructor for stone, lbs Stonewt(); // 默认的构造函数 ~Stonewt(); // 析构函数 void setState(); void resetStonewt(double lbs); void resetStonewt(int stn, double lbs); // overload operator Stonewt operator+(const Stonewt & swt) const; Stonewt operator-(const Stonewt & swt) const; Stonewt operator*(double n) const; Stonewt operator/(const Stonewt & swt) const; friend Stonewt operator*(double n, const Stonewt & swt) { return swt * n; } friend std::ostream & operator<<(std::ostream & os, const Stonewt & swt); // void show_lbs() const; // show weight in pounds format // void show_stn() const; // show weight in stone format};#endif /* __STONEWT2_H__ */