C++ Premier Plus 6th edition
阿新 • • 發佈:2018-12-20
vect.h
// 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 // Newly added:remove mag and ang // double mag; // length of vector // double ang; // direction of vector in degrees Mode mode; // RECT or POL // private methods for setting values // Newly added: as we use magval() and angval(), and don't store mag and ang // therefor no need to keep these 2 data components // void set_mag(); // void set_ang(); void set_x(double mag, double ang); void set_y(double mag, double ang); 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 // Newly added: replace mag with its expression double magval() const {return sqrt(x * x + y * y);} // report magnitude double angval() const { if (x == 0.0 && y == 0.0) return 0.0; else return atan2(y, x); }// 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
vect.cpp
// 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 // set x from polar coordinate // Newly added:alter,consider replace mag with magval(), ang with angval() // but magval() needs x to to calculate,they can't help each other void Vector::set_x(double mag,double ang) { x = mag * cos(ang); } // set y from polar coordinate // Newly added:alter,replay mag with magval(), ang with angval() void Vector::set_y(double mag, double ang) { y = mag * sin(ang); } // public methods // Newly added: remove mag and ang 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; // Newly added:remove these 2 methods // set_mag(); // set_ang(); } else if (form == POL) { // Newly added:remove these 2 variable // mag = n1; // ang = n2 / Rad_to_deg; // inside(),use n1,n2 as mag,ang set_x(n1,n2); set_y(n1,n2); } else { cout << "Incorrect 3rd argument to Vector() -- "; cout << "vector set to 0\n"; // Newly added:remove these 2 variable 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; // Newly added:remove these 2 methods // set_mag(); // set_ang(); } else if (form == POL) { // Newly added:remove these 2 variable // mag = n1; // ang = n2 / Rad_to_deg; set_x(n1, n2); set_y(n1, n2); } else { cout << "Incorrect 3rd argument to Vector() -- "; cout << "vector set to 0\n"; // Newly added:remove these 2 variable x = y = 0.0; mode = RECT; } } Vector::~Vector() // destructor { } void Vector::polar_mode() // set to polar mode { mode = POL; } void Vector::rect_mode() // set to rectangular mode { mode = RECT; } // operator overloading // add two Vectors Vector Vector::operator+(const Vector & b) const { return Vector(x + b.x, y + b.y); } // subtract Vector b from a Vector Vector::operator-(const Vector & b) const { return Vector(x - b.x, y - b.y); } // reverse sign of Vector Vector Vector::operator-() const { return Vector(-x, -y); } // multiply vector by n Vector Vector::operator*(double n) const { return Vector(n * x, n * y); } // friend methods // multiply n by Vector a Vector operator*(double n, const Vector & a) { return a * n; } // display rectangular coordinates if mode is RECT, // else display polar coordinates if mode is POL std::ostream & operator<<(std::ostream & os, const Vector & v) { if (v.mode == Vector::RECT) os << "(x,y) = (" << v.x << ", " << v.y << ")"; else if (v.mode == Vector::POL) { os << "(m,a) = (" << v.magval() << ", " << v.angval() * Rad_to_deg << ")"; } else os << "Vector object mode is invalid"; return os; } } // end namespace VECTOR
main
// 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, Vector::POL); result = result + step; steps++; } cout << "After " << steps << " steps, the subject " "has the following location:\n"; cout << result << endl; result.polar_mode(); cout << " or\n" << result << endl; cout << "Average outward distance per step = " << result.magval()/steps << endl; steps = 0; result.reset(0.0, 0.0); cout << "Enter target distance (q to quit): "; } cout << "Bye!\n"; /* keep window open cin.clear(); while (cin.get() != '\n') continue; cin.get(); */ return 0; }