目录
定义一个Time类(Version 2),加法用运算符重载实现
定义一个Time类(Version 3),加法,减法及乘法用运算符重载实现
定义一个Time类(Version 4),乘法用友元运算符重载实现
本章小结
本章介绍了定义和使用类的许多重要方面,其中的一些内容可能比较难理解,但随着实践经验的不断增加,您将逐步掌握他们。
一般来说,访问私有类成员的唯一方法是使用类方法。C++使用友元函数来避幵这种限制。要让函数为友元,需要在类声明中声明该函数,并在声明前加上关键字friend。
C++扩展了对运算符的重载,允许自定义特殊的运算符函数,这种函数描述了特定的运算符与类之间的关系。 运算符函数可以是类成员函数,也可以是友元函数(有一些运算符函数只能是类成员函数)。要调用运算符函数, 可以直接调用该函数,也可以以通常的句法使用被重载的运算符。对于运算符op,其运算符函数的格式如下:
operatorop(argument-list)
argument-list表示该运算符的操作数。如果运算符函数是类成员函数,则第一个操作数是调用对象, 它不在argument-list中。例如,本章通过为Vector类定义operator+()成员函数重载了加法。如果up、right 和result都是Vector对象,则可以使用下面的任何一条语句来调用矢量加法:
result = up.operator+(right);
result = up + right;
在第二条语句中,由于操作数up和right的类型都是Vector,因此C++将使用Vector的加法定义。
当运算符函数是成员函数时,则第一个操作数将是调用该函数的对象.例如,在前面的语句中,up对象是调用函数的对象。定义运算符函数时,如果要使其第一个操作数不是类对象,则必须使用友元函数。 这样就可以将操作数按所需的顺序传递给函数了。
最常见的运算符重载任务之一是定义<<运算符,使之可与cout —起使用,来显示对象的内容。要让ostream对象成为第一个操作数,需要将运算符函数定义为友元:要使重新定义的运算符能与其自身拼接, 需要将返回类型声明为ostream&。下面的通用格式能够满足这种要求:
ostream & operator<< (ostream & os, const c_name & obj)
{
os << ... ; // display object contents
return os;
}
然而,如果类包含这样的方法,它返回需要显示的数据成员的值,则可以使用这些方法,无需在 operator<<()中直接访问这些成员。这种情况下:函数不必(也不应是)友元。
C++允许指定在类和基本类型之间进转换的方式。首先,任何接受唯一一个参数的构造函数都可被用作转换函数,将类型与该参数相同的值转换为类。如果将类型与该参数相同的值赋给对象,则C++将自动调用该构造函数。例如,假设有一个String类,它包含一个将char*值作为其唯一参数的构造函数,那么如果bean是String对象,则可以使用下面的语句:
bean = "pinto"; //If converts type char * to type String
然而,如果在该构造函数的声明前加上了关键宁•explicit,则该构造函数将只能用于显式转换:
bean = String("pinto"); // converts type char * to type String explicitly
要将类对象转换为其他类型,必须定义转换函数,指出如何进行这种转换。转换函数必须是成员函数。 将类对象转换为typcName类型的转换函数的原型如下:
operator typeName();
注意,转换函数没有返回类型、没有参数,但必须返回转换后的值(虽然没有声明返回类型)。例如, 下面是将Vector转换为double类型的函数:
Vector::operator doublet)
{
return a_double_value;
}
经验表明,最好不要依赖于这种隐式转换函数。
您可能已经注意到了,与简单的C-风格结构相比,使用类时,必须更谨慎、更小心,但作为补偿,它们为我们完成的工作也更多。
程序清单
定义一个Time类(Version 1),加法用函数实现
11.1 mytime0.h Time类的声明,加法用Sum()时间
//mytime0.h -- Time class before operator overloading
#ifndef MYTIME0_H_
#define MYTIME0_H_
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 Sum(const Time &t)const;
void Show() const;
};
#endif // !MYTIME0_H_
11.2 mytime0.cpp 类方法的定义
//mytime0.cpp -- implementing Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{
hours = minutes = 0;
}
Time::Time(int h, int m /* = 0 */)
{
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 /* = 0 */, int m /* = 0 */)
{
hours = h;
minutes = m;
}
Time Time::Sum(const Time &t)const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
void Time::Show()const
{
std::cout << hours << " hours, " << minutes << " minutes";
}
11.3 usetime0.cpp 使用Time类
//usetime0.cpp -- using the first draft of the Time class
//compile usetime0.cpp and mytime0.cpp together
#include <iostream>
#include "mytime0.h"
int usetime0()
{
using namespace std;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout << "planning time = ";
planning.Show();
cout << endl;
cout << "coding time = ";
coding.Show();
cout << endl;
cout << "fixing time = ";
fixing.Show();
cout << endl;
total = coding.Sum(fixing);
cout << "coding.Sum(fixing) = ";
total.Show();
cout << endl;
return 0;
}
定义一个Time类(Version 2),加法用运算符重载实现
11.4 mytime1.h Time类的声明, 加法用运算符重载来实现
//mytime1.h -- Time class before operator overloading
#ifndef MYTIME1_H_
#define MYTIME1_H_
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;
void Show() const;
};
#endif // !MYTIME1_H_
11.5 mytime1.cpp Time类方法的定义
//mytime1.cpp -- implementing Time methods
#include <iostream>
#include "mytime1.h"
Time::Time()
{
hours = minutes = 0;
}
Time::Time(int h, int m /* = 0 */)
{
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 /* = 0 */, int m /* = 0 */)
{
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;
}
void Time::Show()const
{
std::cout << hours << " hours, " << minutes << " minutes";
}
11.6 使用Time类
//usetime1.cpp -- using the second draft of the Time class
//compile usetime1.cpp and mytime0.cpp together
#include <iostream>
#include "mytime1.h"
int main()
{
using namespace std;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout << "planning time = ";
planning.Show();
cout << endl;
cout << "coding time = ";
coding.Show();
cout << endl;
cout << "fixing time = ";
fixing.Show();
cout << endl;
total = coding + fixing;
cout << "coding + fixing = ";
total.Show();
cout << endl;
Time morefixing(3, 28);
cout << "more fixing time = ";
morefixing.Show();
cout << endl;
total = morefixing.operator+(total);
//function notation
cout << "morefixing.operator+(total) = ";
total.Show();
cout << endl;
return 0;
}
定义一个Time类(Version 3),加法,减法及乘法用运算符重载实现
11.7 mytime2.h Time类的声明
//mytime2.h -- Time class before operator overloading
#ifndef MYTIME2_H_
#define MYTIME2_H_
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;
void Show() const;
};
#endif // !MYTIME2_H_
11.8 mytime2.cpp Time类方法的定义
//mytime2.cpp -- implementing Time methods
#include <iostream>
#include "mytime2.h"
Time::Time()
{
hours = minutes = 0;
}
Time::Time(int h, int m /* = 0 */)
{
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 /* = 0 */, int m /* = 0 */)
{
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;
}
void Time::Show()const
{
std::cout << hours << " hours, " << minutes << " minutes";
}
11.9 usetime2.cpp 使用Time类
//usetime2.cpp -- using the third draft of the Time class
//compile usetime2.cpp and mytime2.cpp together
#include <iostream>
#include "mytime2.h"
int main()
{
using namespace std;
Time weeding(4, 35);
Time waxing(2, 47);
Time total;
Time diff;
Time adjusted;
cout << "weeding time = ";
weeding.Show();
cout << endl;
cout << "waxing time = ";
waxing.Show();
cout << endl;
total = weeding + waxing;
cout << "total work time = ";
total.Show();
cout << endl;
diff = weeding - waxing;
cout << "weeding time - waxing time = ";
diff.Show();
cout << endl;
adjusted = total * 1.5;
//function notation
cout << "adjusted work time = ";
adjusted.Show();
cout << endl;
return 0;
}
定义一个Time类(Version 4),乘法用友元运算符重载实现
11.10 mytime3.h Time类的声明
//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;
}
friend std::ostream & operator << (std::ostream & os, const Time & t);
};
#endif // !MYTIME3_H_
11.11 mytime3.cpp Time类方法的定义
//mytime3.cpp -- implementing Time methods
#include "mytime3.h"
Time::Time()
{
hours = minutes = 0;
}
Time::Time(int h, int m /* = 0 */)
{
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 /* = 0 */, int m /* = 0 */)
{
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;
}
11.12 使用Time类
//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 namespace std;
Time aida(3, 35);
Time tosca(2, 48);
Time temp;
cout << "Aida and Tosca:\n";
cout << aida << "; " << tosca << endl;
temp = aida + tosca;
cout << "Aida + Tosca: " << temp << endl;
temp = aida * 1.17;
cout << "Aida * 1.17: " << temp << endl;
cout << "10.0 * Tosca: " << 10.0 * tosca << endl;
return 0;
}
定义一个矢量类 Vector
11.13 vector.h Vector类的声明
//vector.h -- Vector class with <<, mode state
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
namespace VECTOR
{
class Vector
{
public:
enum Mode {RECT, POL};
private:
double x;
double y;
double mag;
double ang;
Mode mode;
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; }
double yval() const { return y; }
double magval() const { return mag; }
double angval() const { return ang; }
void polar_mode();
void rect_mode();
Vector operator + (const Vector & b) const;
Vector operator - (const Vector & b) const;
Vector operator - () const;
Vector operator * (double n) const;
friend Vector operator * (double n, const Vector & a);
friend std::ostream & operator << (std::ostream & os, const Vector & v);
};
}
#endif // ! VECTOR_H_
11.14 vector.cpp Vector类方法的定义
//verctor.cpp -- methods for the Vector class
#include <cmath>
#include "vector.h"
using namespace std;
namespace VECTOR
{
const double Rad_to_deg = 45.0 / atan(1.0);
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);
}
void Vector::set_x()
{
x = mag * cos(ang);
}
void Vector::set_y()
{
y = mag * sin(ang);
}
Vector::Vector()
{
x = y = mag = ang = 0.0;
mode = RECT;
}
Vector::Vector(double n1, double n2, Mode form /* = RECT */)
{
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;
}
}
void Vector::reset(double n1, double n2, Mode form /* = RECT */)
{
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()
{
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
mode = RECT;
}
Vector Vector::operator + (const Vector & b) const
{
return Vector(x + b.x, y + b.y);
}
Vector Vector::operator - (const Vector & b) const
{
return Vector(x - b.x, y - b.y);
}
Vector Vector::operator - () const
{
return Vector(-x, -y);
}
Vector Vector::operator * (double n) const
{
return Vector(n*x, n*y);
}
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;
}
}
11.15 randwalk.cpp 使用Vector类来模拟随机漫步
//randwalk.cpp -- using the Vector class
//compile with the vect.cpp file
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "vector.h"
int main()
{
using namespace std;
using VECTOR::Vector;
srand(time(0));
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" << result << endl;
result.polar_mode();
cout << " or\n" << result << endl;
cout << "Average out ward 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";
cin.clear();
while (cin.get() != '\n')
continue;
return 0;
}
类的自动转换和强制转换
11.16 stonewt.h
//stonewt.h -- definition for the Stonewt class
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
enum {Lbs_per_stn = 14};
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
Stonewt(int stn, double lbs);
Stonewt();
~Stonewt();
void show_lbs() const;
void show_stn() const;
};
#endif // !STONEWT_H_
11.17 stonewt.cpp
//stonewt.cpp -- Stonewt methods
#include <iostream>
#include "stonewt.h"
using namespace std;
Stonewt::Stonewt(double lbs)
{
stone = int(lbs) / Lbs_per_stn;
pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
}
Stonewt::Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn + lbs;
}
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
}
Stonewt::~Stonewt()
{
}
void Stonewt::show_stn() const
{
cout << stone << " stone, " << pds_left << "pounds\n";
}
void Stonewt::show_lbs() const
{
cout << pounds << " pounds\n";
}
11.18 stone.cpp
//stone.cpp -- user-defined conversions
// compile with stonewt.cpp
#include <iostream>
#include "stonewt.h"
void display(const Stonewt & st, int n);
using namespace std;
int main()
{
Stonewt incognito = 275;
Stonewt wolfe(285.7);
Stonewt taft(21, 8);
cout << "The celebrity weighed ";
incognito.show_stn();
cout << "The detective weighed ";
wolfe.show_stn();
cout << "The president weighed ";
taft.show_lbs();
incognito = 276.8;
taft = 325;
cout << "After dinner, the celebrity weighed ";
incognito.show_stn();
cout << "After dinner, the President weighed ";
taft.show_lbs();
display(taft, 2);
cout << "The wrestler weighed even more.\n";
display(422, 2);
cout << "No stone left unearned\n";
return 0;
}
void display(const Stonewt & st, int n)
{
for (int i = 0; i < n; i++)
{
cout << "Wow! ";
st.show_stn();
}
}
11.19 stonewt1.h
//stonewt1.h -- revised definition for the Stonewt class
#ifndef STONEWT1_H_
#define STONEWT1_H_
class Stonewt
{
private:
enum { Lbs_per_stn = 14 };
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
Stonewt(int stn, double lbs);
Stonewt();
~Stonewt();
void show_lbs() const;
void show_stn() const;
operator int() const;
operator double() const;
};
#endif // !STONEWT1_H_
11.20 stonewt1.cpp
//stonewt1.cpp -- Stonewt class methods + conversion function
#include <iostream>
#include "stonewt1.h"
using namespace std;
Stonewt::Stonewt(double lbs)
{
stone = int(lbs) / Lbs_per_stn;
pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
}
Stonewt::Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn + lbs;
}
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
}
Stonewt::~Stonewt()
{
}
void Stonewt::show_stn() const
{
cout << stone << " stone, " << pds_left << "pounds\n";
}
void Stonewt::show_lbs() const
{
cout << pounds << " pounds\n";
}
Stonewt::operator int() const
{
return int(pounds + 0.5);
}
Stonewt::operator double() const
{
return pounds;
}
11.21 stone1.cpp
//stone1.cpp -- user-defined conversion functions
//compile with stonewt1.cpp
#include <iostream>
#include "stonewt1.h"
int main()
{
using namespace std;
Stonewt poppins(9, 2.8);
double p_wt = poppins;
cout << "Convert to double => ";
cout << "Poppins: " << p_wt << " pounds.\n";
cout << "Convert to int => ";
cout << "Poppins: " << int(poppins) << " pounds.\n";
return 0;
}
课后编程习题
习题1
//vector.h
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
namespace VECTOR
{
class Vector
{
public:
enum Mode { RECT, POL };
private:
double x;
double y;
double mag;
doubleang;
Mode mode;
voidset_mag();
voidset_ang();
voidset_x();
voidset_y();
public:
Vector();
Vector(double n1, double n2, Mode form = RECT);
void reset(double n1, double n2, Mode form = RECT);
~Vector();
doublexval()const{ return x; }
doubleyval()const{ return y; }
doublemagval()const { return mag; }
doubleangval()const { return ang; }
voidpolar_mode();
voidrect_mode();
Vector operator+(const Vector &b)const;
Vector operator-(const Vector &b)const;
Vector operator-()const;
Vector operator*(double n)const;
friend Vector operator*(double n, const Vector &a);
friend ostream& operator<<(ostream&os, const Vector &v);
};
}
#endif
//vector.cpp
#include "vector.h"
namespace VECTOR
{
const double Rad_to_deg = 45.0 / atan(1.0);
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);
}
void Vector::set_x()
{
x = mag * cos(ang);
}
void Vector::set_y()
{
y = mag * sin(ang);
}
Vector::Vector()
{
x = y = mag = ang = 0.0;
mode = RECT;
}
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;
}
}
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()
{
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
mode = RECT;
}
Vector Vector::operator+(const Vector &b)const
{
return Vector(x + b.x, y + b.y);
}
Vector Vector::operator-(const Vector &b)const
{
return Vector(x - b.x, y - b.y);
}
Vector Vector::operator-()const
{
return Vector(-x, -y);
}
Vector Vector::operator*(double n)const
{
return Vector(n*x, n*y);
}
Vector operator*(double n, const Vector &a)
{
return a*n;
}
ostream&operator<<(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;
}
}
//randwalk.cpp
#include "vector.h"
int main()
{
using VECTOR::Vector;
srand(time(0));
double direction;
Vector step;
Vector result(0.0, 0.0);
unsigned long steps = 0;
double target;
double dstep;
ofstream fout;
fout.open("savesteps.txt");
cout<< "Enter target distance (q to quit): ";
while (cin>> target)
{
fout<< "Enter step length: ";
if (!(cin>>dstep))
break;
cout<< "Target Distance: " << target << " Step Size: " <<dstep<<endl;
while (result.magval() < target)
{
fout<< steps << ": " << result <<endl;
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;
fout<< "After " << steps << " steps, the subject "
"has the following location:\n";
fout<< result <<endl;
result.polar_mode();
cout<< " or\n" << result <<endl;
cout<< "Average outward distance per step = " <<result.magval() / steps <<endl;
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";
cin.clear();
while (cin.get() != '\n')
continue;
cin.get();
return 0;
}
习题2
//vector.h
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
namespace VECTOR
{
class Vector
{
public:
enum Mode { RECT, POL };
private:
double x;
double y;
Mode mode;
doubleset_mag()const;
doubleset_ang()const;
voidset_x(double mag, double ang);
voidset_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();
doublexval()const { return x; }
doubleyval()const { return y; }
doublemagval()const { return set_mag(); }
doubleangval()const { return set_ang(); }
voidpolar_mode();
voidrect_mode();
Vector operator+(const Vector &b)const;
Vector operator-(const Vector &b)const;
Vector operator-()const;
Vector operator*(double n)const;
friend Vector operator*(double n, const Vector &a);
friend ostream& operator<<(ostream&os, const Vector &v);
};
}
#endif
//vector.cpp
#include "vector.h"
namespace VECTOR
{
const double Rad_to_deg = 45.0 / atan(1.0);
double Vector::set_mag()const
{
return sqrt(x * x + y * y);
}
double Vector::set_ang()const
{
if (x == 0.0 && y == 0.0)
return 0.0;
else
return atan2(y, x);
}
void Vector::set_x(double mag, double ang)
{
x = mag * cos(ang);
}
void Vector::set_y(double mag, double ang)
{
y = mag * sin(ang);
}
Vector::Vector()
{
x = y = 0.0;
mode = RECT;
}
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;
}
}
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()
{
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
mode = RECT;
}
Vector Vector::operator+(const Vector &b)const
{
return Vector(x + b.x, y + b.y);
}
Vector Vector::operator-(const Vector &b)const
{
return Vector(x - b.x, y - b.y);
}
Vector Vector::operator-()const
{
return Vector(-x, -y);
}
Vector Vector::operator*(double n)const
{
return Vector(n*x, n*y);
}
Vector operator*(double n, const Vector &a)
{
return a * n;
}
ostream&operator<<(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.set_mag() << ", "
<< v.set_ang()*Rad_to_deg << ")";
}
else
os << "Vector object mode is invalid";
return os;
}
}
//randwalk.cpp
#include "vector.h"
int main()
{
using VECTOR::Vector;
srand(time(0));
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";
cin.clear();
while (cin.get() != '\n')
continue;
cin.get();
return 0;
}
习题3
3、
//vector.h
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
namespace VECTOR
{
class Vector
{
public:
enum Mode { RECT, POL };
private:
double x;
double y;
double mag;
double ang;
Mode mode;
voidset_mag();
voidset_ang();
voidset_x();
voidset_y();
public:
Vector();
Vector(double n1, double n2, Mode form = RECT);
void reset(double n1, double n2, Mode form = RECT);
~Vector();
doublexval()const { return x; }
doubleyval()const { return y; }
doublemagval()const { return mag; }
doubleangval()const { return ang; }
voidpolar_mode();
voidrect_mode();
Vector operator+(const Vector &b)const;
Vector operator-(const Vector &b)const;
Vector operator-()const;
Vector operator*(double n)const;
friend Vector operator*(double n, const Vector &a);
friend ostream& operator<<(ostream&os, const Vector &v);
};
}
#endif
//vector.cpp
#include "vector.h"
namespace VECTOR
{
const double Rad_to_deg = 45.0 / atan(1.0);
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);
}
void Vector::set_x()
{
x = mag * cos(ang);
}
void Vector::set_y()
{
y = mag * sin(ang);
}
Vector::Vector()
{
x = y = mag = ang = 0.0;
mode = RECT;
}
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;
}
}
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()
{
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
mode = RECT;
}
Vector Vector::operator+(const Vector &b)const
{
return Vector(x + b.x, y + b.y);
}
Vector Vector::operator-(const Vector &b)const
{
return Vector(x - b.x, y - b.y);
}
Vector Vector::operator-()const
{
return Vector(-x, -y);
}
Vector Vector::operator*(double n)const
{
return Vector(n*x, n*y);
}
Vector operator*(double n, const Vector &a)
{
return a * n;
}
ostream&operator<<(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;
}
}
//randwalk.cpp
#include "vector.h"
int main()
{
using VECTOR::Vector;
srand(time(0));
double direction;
Vector step;
Vector result(0.0, 0.0);
unsigned long steps = 0;
double target;
double dstep;
double numbers, N;
double Min, Max, Sum, Average;
cout << "Enter target distance: ";
cin >> target;
cout << "Enter step length: ";
cin >> dstep;
cout << "Enter test numbers: ";
cin >> numbers;
N = numbers;
Min = Max = Sum = Average = 0.0;
while (numbers)
{
while (result.magval() < target)
{
direction = rand() % 360;
step.reset(dstep, direction, Vector::POL);
result = result + step;
steps++;
}
cout << "After " << steps << " steps once a walk\n";
if (Min == 0 || Max == 0)
Min = Max = steps;
if (Min > steps)
Min = steps;
if (Max < steps)
Max = steps;
Sum += steps;
numbers--;
steps = 0;
result.reset(0.0, 0.0);
}
Average = Sum / N;
cout << "Max steps is " << Max << endl;
cout << "Min steps is " << Min << endl;
cout << "Average steps is " << Average << endl;
cout << "Bye!\n";
cin.clear();
while (cin.get() != '\n')
continue;
cin.get();
return 0;
}
习题4
//mytime.h
#ifndef MYTIME_H_
#define MYTIME_H_
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
voidAddMin(int m);
voidAddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator*(double n)const;
friend Time operator-(const Time &t1, const Time &t2);
friend Time operator+(const Time &t1, const Time &t2);
friend Time operator*(double m, const Time &t)
{
return t * m;
}
friend ostream& operator<<(ostream&os, const Time &t);
};
#endif
//mytime.cpp
#include "mytime.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 = t1.minutes + 60 * t1.hours;
tot2 = t2.minutes + 60 * t2.hours;
diff.minutes = (tot1 - tot2) % 60;
diff.hours = (tot1 - tot2) / 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;
}
ostream&operator<<(ostream&os, const Time &t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
return os;
}
//usetime.cpp
#include "mytime.h"
int main()
{
Time aida(3, 35);
Time tosca(2, 48);
Time temp;
cout << "Aida and Tosca:\n";
cout << aida << "; " << tosca << endl;
temp = aida + tosca;
cout << "Aida + Tosca: " << temp << endl;
temp = aida - tosca;
cout << "Aida - Tosca: " << temp << endl;
temp = aida * 1.17;
cout << "Aida * 1.17: " << temp << endl;
cout << "10.0 * Tosca: " << 10.0 * tosca << endl;
cin.get();
return 0;
}
习题5
//stonewt.h
#ifndef STONEWT_H_
#define STONEWT_H_
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
classStonewt
{
public:
enum Mode { STN, INPD, FPD };
private:
static int constLbs_per_stn = 14;
int stone;
double pds_left;
double pounds;
int pounds_int;
Mode mode;
void set_stn();
void set_pds();
void set_pds_int();
public:
Stonewt(double lbs, Mode form);
Stonewt(int stn, double lbs, Mode form);
Stonewt();
~Stonewt();
voidstn_mode();
voidpds_mode();
voidint_pds_mode();
operatorint()const;
operator double()const;
Stonewt operator+(const Stonewt&st)const;
Stonewt operator-(const Stonewt&st)const;
Stonewt operator*(double n)const;
friend Stonewt operator*(double n, const Stonewt&st);
friend ostream&operator<<(ostream&os, const Stonewt&st);
};
#endif
//stonewt.cpp
#include "stonewt.h"
voidStonewt::set_stn()
{
stone = int(pounds) / Lbs_per_stn;
pds_left = int(pounds) % Lbs_per_stn + pounds - int(pounds);
}
voidStonewt::set_pds()
{
pounds = stone * Lbs_per_stn + pds_left;
}
voidStonewt::set_pds_int()
{
pounds_int = int(pounds);
}
Stonewt::Stonewt(double lbs, Mode form)
{
mode = form;
if (form == STN)
{
stone = int(lbs) / Lbs_per_stn;
pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
set_pds();
set_pds_int();
}
else if (form == INPD)
{
pounds_int = int(lbs);
pounds = lbs;
set_stn();
}
else if (form == FPD)
{
pounds = lbs;
set_pds_int();
set_stn();
}
else
{
cout << "Incorrect 3rd argument to Stonewt() -- ";
cout << "Stonewt set to 0\n";
stone = pounds = pds_left = 0;
mode = STN;
}
}
Stonewt::Stonewt(int stn, double lbs, Mode form)
{
mode = form;
if (form == STN)
{
stone = stn;
pds_left = lbs;
set_pds();
set_pds_int();
}
else if (form == INPD)
{
pounds_int = int(stn*Lbs_per_stn + lbs);
pounds = stn * Lbs_per_stn + lbs;
set_stn();
}
else if (form == FPD)
{
pounds = stn * Lbs_per_stn + lbs;
set_pds_int();
set_stn();
}
else
{
cout << "Incorrect 3rd argument to Stonewt() -- ";
cout << "Stonewt set to 0\n";
stone = pounds = pds_left = 0;
mode = STN;
}
}
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
mode = STN;
}
Stonewt::~Stonewt()
{
}
void Stonewt::stn_mode()
{
mode = STN;
}
void Stonewt::pds_mode()
{
mode = FPD;
}
void Stonewt::int_pds_mode()
{
mode = INPD;
}
Stonewt::operator int()const
{
return int(pounds + 0.5);
}
Stonewt::operator double()const
{
return pounds;
}
Stonewt Stonewt::operator+(const Stonewt&st)const
{
return Stonewt(pounds + st.pounds, st.mode);
}
Stonewt Stonewt::operator-(const Stonewt&st)const
{
return Stonewt(pounds - st.pounds, st.mode);
}
Stonewt Stonewt::operator*(double n)const
{
return Stonewt(pounds*n, mode);
}
Stonewt operator*(double n, const Stonewt&st)
{
return Stonewt(n*st.pounds, st.mode);
}
ostream&operator<<(ostream&os, const Stonewt&st)
{
if (st.mode == Stonewt::STN)
os << st.stone << " stone, " << st.pds_left << " pounds\n";
else if (st.mode == Stonewt::INPD)
os << st.pounds_int << " pounds(int)\n";
else if (st.mode == Stonewt::FPD)
os << st.pounds << " pounds(double)\n";
else
os << "Error in type\n";
return os;
}
//stone.cpp
#include "stonewt.h"
int main()
{
Stonewt incognito(275, Stonewt::FPD);
Stonewt wolfe(285.7, Stonewt::STN);
Stonewt taft(21, 8, Stonewt::INPD);
Stonewt temp;
cout << "The celebrity weighed ";
cout << incognito << endl;
cout << "The detective weighed ";
cout << wolfe << endl;
cout << "The President weighed ";
cout << taft << endl;
temp = incognito + wolfe;
cout << "Incognito + Wolfe = " << temp << endl;
temp = wolfe - incognito;
cout << "Wolfe - Incognito = " << temp << endl;
temp = taft * 10.0;
cout << "Taft * 10.0 = " << temp << endl;
temp = 10.0 * taft;
cout << "10.0 * Taft = " << temp << endl;
cin.get();
return 0;
}
习题6
//stonewt.h
#ifndef STONEWT_H_
#define STONEWT_H_
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
class Stonewt
{
private:
enum { Lbs_per_stn = 14 };
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
Stonewt(int stn, double lbs);
Stonewt();
~Stonewt();
bool operator<(const Stonewt&st)const;
bool operator<=(const Stonewt&st)const;
bool operator>(const Stonewt&st)const;
bool operator>=(const Stonewt&st)const;
bool operator==(const Stonewt&st)const;
bool operator!=(const Stonewt&st)const;
friend ostream&operator<<(ostream&os, const Stonewt&st);
};
#endif
//stonewt.cpp
#include "stonewt.h"
Stonewt::Stonewt(double lbs)
{
stone = int(lbs) / Lbs_per_stn;
pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
}
Stonewt::Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn + lbs;
}
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
}
Stonewt::~Stonewt()
{
}
bool Stonewt::operator<(const Stonewt&st)const
{
if (pounds < st.pounds)
return true;
else
return false;
}
bool Stonewt::operator<=(const Stonewt&st)const
{
if (pounds <= st.pounds)
return true;
else
return false;
}
bool Stonewt::operator>(const Stonewt&st)const
{
if (pounds > st.pounds)
return true;
else
return false;
}
bool Stonewt::operator>=(const Stonewt&st)const
{
if (pounds >= st.pounds)
return true;
else
return false;
}
bool Stonewt::operator==(const Stonewt&st)const
{
if (pounds == st.pounds)
return true;
else
return false;
}
bool Stonewt::operator!=(const Stonewt&st)const
{
if (pounds != st.pounds)
return true;
else
return false;
}
ostream&operator<<(ostream&os, const Stonewt&st)
{
os << st.pounds << " pounds\n";
return os;
}
//stone.cpp
#include "stonewt.h"
int main()
{
Stonewt sw[6] = { 10.0, 11.0, 12.5 };
Stonewt temp(11.0);
for (int i = 3; i < 6; i++)
{
double input;
cout << "Enter #" << i + 1 << ": ";
cin >> input;
sw[i] = input;
}
for (inti = 0; i < 6; i++)
cout << "#" << i << ": " << sw[i];
int count = 0;
Stonewt Min = sw[0];
Stonewt Max = sw[0];
for (int i = 0; i < 6; i++)
{
if (Min > sw[i])
Min = sw[i];
if (Max < sw[i])
Max = sw[i];
if (temp >= sw[i])
count++;
}
cout << "The Min pounds: " << Min;
cout << "The Max pounds: " << Max;
cout << "The numbers not under 11 pounds: " << count;
cin.get();
cin.get();
return 0;
}
习题7
//complexh.h
#ifndef COMPLEX_H_
#define COMPLEX_H_
#include <iostream>
#include <string>
#include <stdio.h>
#include <cmath>
using namespace std;
class Complex
{
private:
double real;
double imaginary;
public:
Complex();
Complex(double n1);
Complex(double n1, double n2);
~Complex();
Complex operator+(const Complex &c)const;
Complex operator-(const Complex &c)const;
Complex operator*(const Complex &c)const;
Complex operator*(double n)const;
Complex operator~()const;
friend Complex operator*(double n, const Complex &c);
friend ostream&operator<<(ostream&os, const Complex &c);
friend istream&operator>>(istream&is, Complex &c);
};
#endif
//complex.cpp
#include "complexh.h"
Complex::Complex()
{
real = 0.0;
imaginary = 0.0;
}
Complex::Complex(double n1)
{
real = n1;
imaginary = 0.0;
}
Complex::Complex(double n1, double n2)
{
real = n1;
imaginary = n2;
}
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
{
double real_s;
double imaginary_s;
real_s = real * c.real - imaginary * c.imaginary;
imaginary_s = real * c.imaginary + imaginary * c.real;
return Complex(real_s, imaginary_s);
}
Complex Complex::operator*(double n)const
{
return Complex(n*real, n*imaginary);
}
Complex Complex::operator~()const
{
return Complex(real, -imaginary);
}
Complex operator*(double n, const Complex &c)
{
return Complex(n*c.real, n*c.imaginary);
}
ostream &operator<<(ostream&os, const Complex &c)
{
os << "(" << c.real << ", " << c.imaginary << "i)";
return os;
}
istream &operator>>(istream&is, Complex &c)
{
cout << "Real: ";
if (is >> c.real)
{
cout << "Imaginary: ";
is >> c.imaginary;
}
return is;
}
//useComplex.cpp
#include "complexh.h"
int main()
{
Complex a(3.0, 4.0);
Complex c;
char ch;
cout << "Enter a complex number (q to quit): ";
while (cin >> ch)
{
if (ch == 'q' || ch == 'Q')
break;
else
{
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): ";
}
cout << "Done!\n";
cin.get();
cin.get();
return 0;
}