// 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 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;
}
// constructor 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
{
}
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 operator
Stonewt 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 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;
}
// constructor 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
{
}
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 operator
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);
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 function
complex::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 function
complex 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.h
int 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__ */