这里写目录标题
- 一、复习题
- 二、编程练习
一、复习题
1. 使用成员函数为Stonewt类重载乘法运算符,该运算符将数据成员与double类型的值相乘。注意,当用英石和磅表示时,需要进位。也就是说,将10英石8磅乘以2等于21英石2磅。
答:下面是原Stonewt类的声明,我们在其成员函数中重载乘法运算符(*)。
// Stonewt类声明
class Stonewt
{
private:enum {Lbs_per_stn = 14}; // 1英石等于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; // 以英镑为单位显示体重// 乘法运算符重载Stonewt operator*(double n);
}// 函数定义// Stonewt类的乘法运算符重载
Stonewt Stonewt::operator*(double n) const
{return Stonewt(n*pounds); // 用构造函数创建临时对象返回
}
2. 友元函数与成员函数之间的区别是什么?
答:从性质上看,成员函数是类定义的一部分,由类生成的所有对象均会共享类的一组成员函数。从功能上看,成员函数能够访问类内部的所有数据成员。而友元函数并不是类定义的一部分,而是一个具备特定的类访问权限的函数,友元函数从功能上说也能够直接访问所有类的成员,但是并不能隐式访问,而必须通过成员运算符用于参数传递的对象。
3. 非成员函数必须是友元函数才能访问类成员吗?
答:首先从访问控制上说,使用类对象的程序能直接通过类对象访问所有的公有数据接口,但无法访问类的私有数据接口。通过类的友元函数能够直接访问类内的所有数据成员和函数,包括具有私有访问权限的数据成员和成员函数。因此,片面地认为非成员函数必须是友元函数才能访问类成员是不正确的。
4. 使用友元函数为Stonewt类重载乘法运算符,该运算符将double值与Stone值相乘。
答:使用友元函数需要注意,在函数声明(函数原型)时,需要使用关键字friend,且需要在类内声明。定义时需要在类外,因为友元函数并不是该类的成员函数,函数定义不需要使用friend关键字,也不需要使用类名称限定。(上面有类声明,我就直接写函数声明和定义了)
// Stonewt类声明
class Stonewt
{
private:// ...
public:// ...friend Stonewt operator*(double n, const Stonewt& s);
}// 函数定义
Stone operator*(double n, const Stonewt& s)
{return Stonewt(n*s.pounds); // 依旧使用构造函数创建临时变量返回
}
5. 哪些运算符不能被重载?
答:C++中运算符的重载有一定的限制,重载运算符至少有一个参数是用户自定义的类型,不能创建新的运算符,不能违反原来运算符的语法法则,部分运算符不能重载。不能重载的运算符如下:
a. sizeof——sizeof运算符
b. .——成员运算符
c. .*——成员指针运算符
d. ::——作用域解析运算符
e. ?:——条件运算符
f. typeid——一个RTTI运算符
g. const_cast——强制类型转换运算符
h. dynamic_cast——强制类型转换运算符
i. reintepret_cast——强制类型转换运算符
j. static_cast——强制类型转换运算符
6. 在重载运算符=、()、[]、和->时,有什么限制?
答:首先包含复习题5说明的四条规则,重载运算符至少有一个参数是用户自定义的类型,不能违反运算符原来的语法规则,不能创建新的运算符,部分运算符不能重载。此外,大多数运算符可以通过成员或非成员函数进行重载,但上述四个运算符(=、()、[]和->)只能通过成员函数进行重载,不能使用友元函数进行重载。
7. 为Vector类定义一个转换函数,将Vector类转换为一个double类型的值,后者表示矢量的长度。
答:由于只有一条返回语句,直接在类声明中定义,使其成为内联函数(前缀inline关键字修饰)。
// Vector类声明
class Vector
{
private:// ...
public:// ... operator double() const {return mag;}
}
二、编程练习
1. 修改程序清单11.15,使之将一系列连续的随机漫步者位置写入文件中。对于每个位置,用步号进行标识。另外,使程序将初始条件(目标距离和步长)以及结果小结写入该文件中。该文件内容如下。
Target Distance:100,Step Size:20
0:(x,y)=(0,0)
1:(x,y)=(-11.4715,16.383)
2:(x,y)=(-8.68807,-3.42232)
…
26:(x,y)=(42.2919,-78.2594)
27:(x,y)=(58.6749,-89.7309)
After 27 steps,the subject has the following location:
(x,y)=(58.6749,-89.7309)
or
(m,a)=(107.212,-56.8194)
Average outward distance per step = 3.97081
答:下面是作者重新编写的代码(读者也可以根据书上进行修改,添加头文件<fstream>,然后输出到文件中)。
Vector1.h头文件
#pragma once// 头文件
#include <iostream>// using 声明
using std::cout;
using std::endl;// 名称空间VECTOR
namespace VECTOR
{// using 声明using std::ostream;// Vector类声明class Vector{public:enum Mode{RECT, POL};// 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(); // 使用POL坐标void rect_mode(); // 使用RECT坐标// 运算符重载Vector operator+(const Vector& v) const;Vector operator-(const Vector& v) const;Vector operator-() const;Vector operator*(double n) const;// 友元friend Vector operator*(double n, const Vector& v);friend ostream& operator<<(ostream& os, const Vector& v);};
}
main1.cpp测试文件
// 头文件
#include "Vector1.h"
#include <ctime>
#include <cstdlib>
#include <fstream>// using 编译指令
using VECTOR::Vector;// using 声明
using std::cin;
using std::ofstream;int main()
{// 定位文件ofstream fo;fo.open("rambler.txt", 'w');// 设置随机数种子srand((unsigned)time(0));// 需要的变量double step; // 步长double distance; // 距离int steps = 0; // 走了几步Vector result(0.0, 0.0); // 存储每走一步的结果// 输入距离和步长fo << "Target Distance: ";while (cin >> distance){fo << distance << ", ";fo << "Step Size: ";if (!(cin >> step))break;fo << step << endl;fo << steps << ": " << "(x, y) = "<< "(" << result.xval() << ", "<< result.yval() << ")" << endl;while (result.magval() < distance){double ang = rand() % 360;Vector tmp(step, ang, Vector::POL);result = result + tmp;++steps;fo << steps << ": " << "(x, y) = "<< "(" << result.xval() << ", "<< result.yval() << ")" << endl;}// 按格式输出fo << "After " << steps << "steps, the subject has the following location:\n"<< "(x, y) = " << "(" << result.xval() << ", " << result.yval() << ")\n"<< "or\n" << "(m, a) = " << "(" << result.magval() << ", " << result.angval()<< ")\n";fo << "Average outward distance per step = " << distance / steps << endl;}// 关闭文件fo.close();return 0;
}
Vector1.cpp方法定义文件
// 头文件
#include "Vector1.h"
#include <cmath>// using 声明
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;// 名称空间VECTOR
namespace VECTOR
{// 符号常量const double Rad_to_Deg = 45.0 / atan(1.0); // 1弧度转度// 私有方法定义void Vector::set_mag(){mag_ = sqrt(x_ * x_ + y_ * y_);}void Vector::set_ang(){if (x_ == 0 && y_ == 0)ang_ = 0;elseang_ = atan2(y_, x_); // atan2()先y后x}void Vector::set_x(){x_ = mag_ * sin(ang_);}void Vector::set_y(){y_ = mag_ * cos(ang_);}// 公有方法定义Vector::Vector() // 默认构造函数{x_ = y_ = mag_ = ang_ = 0;mode_ = RECT;}Vector::Vector(double n1, double n2, Mode form) // 带参数的构造函数,默认为直角坐标表示方式{// 获取初始化模型mode_ = form;if (mode_ == RECT) // 直角形式{x_ = n1;y_ = n2;set_mag();set_ang();}else if (mode_ == POL){mag_ = n1;ang_ = n2 / Rad_to_Deg; // 以度数输入,转换为弧度存储set_x();set_y();}else{cout << "没有这个模型,按照默认构造函数初始化。" << endl;x_ = y_ = mag_ = ang_ = 0;mode_ = RECT;}}void Vector::reset(double n1, double n2, Mode form){// 获取初始化模型mode_ = form;if (mode_ == RECT) // 直角形式{x_ = n1;y_ = n2;set_mag();set_ang();}else if (mode_ == POL){mag_ = n1;ang_ = n2 / Rad_to_Deg; // 以度数输入,转换为弧度存储set_x();set_y();}else{cout << "没有这个模型,按照默认构造函数初始化。" << endl;x_ = y_ = mag_ = ang_ = 0;mode_ = RECT;}}Vector::~Vector() // 析构函数{}void Vector::polar_mode() // 使用POL坐标{mode_ = POL;}void Vector::rect_mode() // 使用RECT坐标{mode_ = RECT;}// 运算符重载Vector Vector::operator+(const Vector& v) const{return Vector(x_ + v.x_, y_ + v.y_);}Vector Vector::operator-(const Vector& v) const{return Vector(x_ - v.x_, y_ - v.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& v){return v * n;}ostream& operator<<(ostream& os, const Vector& v){if (v.mode_ == Vector::RECT){os << "(x, y) = " << "(" << v.x_<< ", " << v.y_ << ")" << endl;}else if (v.mode_ == Vector::POL){os << "(m, a) = " << "(" << v.mag_<< ", " << v.ang_ << ")" << endl;}else{os << "没有这个形式.\n";}return os;}
}
运行结果
2. 对Vector类的头文件(程序清单11.13)和实现文件(程序清单11.14)进行修改,使其不再存储向量的长度和角度,而在调用magval()和angval()时计算它们。应保留公有接口不变(公有方法及其参数不变),但对私有部分(包括一些私有方法)和方法进行修改。然后,使用程序清单11.15对修改后的版本进行测试,结果应该与以前相同,因为Vector类的公有接口与原来相同。
答:删除私有成员变量mag和ang,删除私有成员函数set_mag()和set_ang(),修改私有成员函数set_x()和set_y()。修改公有成员函数中所有涉及mag和ang的函数。
Vector2.h头文件
#pragma once// 头文件
#include <iostream>// using 声明
using std::cout;
using std::endl;// 名称空间VECTOR
namespace VECTOR
{// using 声明using std::ostream;// Vector类声明class Vector{public:enum Mode { RECT, POL };// RECT表示直角坐标,POL表示极坐标private:double x_; // 横坐标double y_; // 纵坐标Mode mode_; public:// 公有方法声明Vector(); // 默认构造函数Vector(double n1, double n2, Mode form = RECT); // 带参数的构造函数,默认为直角坐标表示方式void reset(double n1, double n2, Mode form = RECT);~Vector(); // 析构函数void set_x(double mag, double ang);void set_y(double mag, double ang);double xval() const { return x_; }double yval() const { return y_; }double magval() const;double angval() const;void polar_mode(); // 使用POL坐标void rect_mode(); // 使用RECT坐标// 运算符重载Vector operator+(const Vector& v) const;Vector operator-(const Vector& v) const;Vector operator-() const;Vector operator*(double n) const;// 友元friend Vector operator*(double n, const Vector& v);friend ostream& operator<<(ostream& os, const Vector& v);};
}
main2.cpp测试文件
// 头文件
#include "Vector2.h"
#include <ctime>
#include <cstdlib>// using 编译指令
using VECTOR::Vector;// using 声明
using std::cin;int main()
{// 所需变量Vector result(0.0, 0.0); // 存储每一步的结果double distance; // 距离double step; // 步长double steps = 0; // 步数// 设置随机数种子srand((unsigned)time(0));// 输入目标距离cout << "Enter target distance (q to quit): ";while (cin >> distance){// 输入步长cout << "Enter step length: ";if (!(cin >> step))break;// 计算while (result.magval() < distance){double angle = rand() % 360;Vector tmp(step, angle, Vector::POL);result = result + tmp;++steps;}// 按格式输出cout << "After " << steps << "steps, the subject has the following location:\n";cout << result;result.polar_mode();cout << "or\n" << result;cout << "Average outward distance per step = " << distance / steps << endl;// 重置数据steps = 0;result.reset(0.0, 0.0);// 下一组cout << "Enter target distance (q to quit): ";}return 0;
}
Vector2.cpp方法定义文件
// 头文件
#include "Vector2.h"
#include <cmath>// using 声明
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;// 名称空间VECTOR
namespace VECTOR
{// 符号常量const double Rad_to_Deg = 45.0 / atan(1.0); // 1弧度转度// 公有方法定义Vector::Vector() // 默认构造函数{x_ = y_ = 0;mode_ = RECT;}Vector::Vector(double n1, double n2, Mode form) // 带参数的构造函数,默认为直角坐标表示方式{// 获取初始化模型mode_ = form;if (mode_ == RECT) // 直角形式{x_ = n1;y_ = n2;}else if (mode_ == POL){set_x(n1, n2 / Rad_to_Deg);set_y(n1, n2 / Rad_to_Deg);}else{cout << "没有这个模型,按照默认构造函数初始化。" << endl;x_ = y_ = 0;mode_ = RECT;}}void Vector::reset(double n1, double n2, Mode form){// 获取初始化模型mode_ = form;if (mode_ == RECT) // 直角形式{x_ = n1;y_ = n2;}else if (mode_ == POL){set_x(n1, n2 / Rad_to_Deg);set_y(n1, n2 / Rad_to_Deg);}else{cout << "没有这个模型,按照默认构造函数初始化。" << endl;x_ = y_ = 0;mode_ = RECT;}}Vector::~Vector() // 析构函数{}double Vector::magval() const{return sqrt(x_ * x_ + y_ * y_);}double Vector::angval() const{if (x_ == 0 && y_ == 0)return 0;elsereturn 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);}void Vector::polar_mode() // 使用POL坐标{mode_ = POL;}void Vector::rect_mode() // 使用RECT坐标{mode_ = RECT;}// 运算符重载Vector Vector::operator+(const Vector& v) const{return Vector(x_ + v.x_, y_ + v.y_);}Vector Vector::operator-(const Vector& v) const{return Vector(x_ - v.x_, y_ - v.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& v){return v * n;}ostream& operator<<(ostream& os, const Vector& v){if (v.mode_ == Vector::RECT){os << "(x, y) = " << "(" << v.x_<< ", " << v.y_ << ")" << endl;}else if (v.mode_ == Vector::POL){os << "(m, a) = " << "(" << v.magval()<< ", " << v.angval() * Rad_to_Deg << ")" << endl;}else{os << "没有这个形式.\n";}return os;}
}
3. 修改程序清单11.15,使之报告N次测试中最高、最低和平均步数(其中N是用户输入的整数),而不是报告每次测试的结果。
答:
// 头文件
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "Vector1.h"int main()
{// using 编译指令using namespace std;// using 声明using VECTOR::Vector;// 设置随机数种子srand((unsigned)time(0));// 所需变量Vector result(0.0, 0.0); // 存储每一步的结果unsigned long steps = 0; // 步数double step; // 步长double target; // 目标距离int max = 0; // 最高步数int min = 0; // 最低步数int sum = 0; // 总步数int times = 0; // 测试次数double average = 0; // 平均步数// 输入cout << "Enter target distance (q to quit): ";while (cin >> target){cout << "Enter step length: ";if (!(cin >> step))break;// 计算while (result.magval() < target){double angle = rand() % 360;Vector tmp(step, angle, Vector::POL);result = result + tmp;++steps;}// 按格式输出cout << "After " << steps << " steps, the subject "<< "has the following location:\n";cout << result << endl;result.polar_mode();cout << "or\n";cout << result << endl;cout << "Average outward distance per step = "<< result.magval() / steps << endl;// 比较与统计if (steps > max)max = steps;if (min == 0 || steps < min)min = steps;sum += steps;++times;// 重置,下一组steps = 0;result.reset(0.0, 0.0);cout << "Enter target distance (q to quit): ";}cout << "测试次数: " << times << endl;cout << "最高步数: " << max << endl;cout << "最低步数: " << min << endl;cout << "平均步数: " << (double)sum / times << endl;cout << "Bye!\n";return 0;
}
4. 重新编写最后的Time类示例(程序清单11.10、程序清单11.11和程序清单11.12),使用友元函数来实现所有的重载运算符。
答:把原来的成员函数运算符重载用友元来实现。
Time.h头文件
#pragma once// 头文件
#include <iostream>// using 声明
using std::cout;
using std::endl;// Time类声明
class Time
{
private:int hours_; // 小时数int minutes_; // 分钟数
public:Time(); // 默认构造函数Time(int h, int m);void AddMin(int m);void AddHr(int h);// 新友元friend Time operator+(const Time& t1, const Time& t2);friend Time operator-(const Time& t1, const Time& t2);friend Time operator*(const Time& t1, double n);// 原友元friend Time operator*(double n, const Time& t) { return t * n; }friend std::ostream& operator<<(std::ostream& os, const Time& t);
};
main4.cpp测试文件
// 头文件
#include "Time.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 * 1.17;cout << "Aida * 1.17: " << temp << endl;cout << "10.0 * Tosca: " << 10.0 * tosca << endl;return 0;
}
Time.cpp方法定义文件
// 头文件
#include "Time.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;
}// 新友元
Time operator+(const Time& t1, const Time& t2)
{int sum_m = t1.minutes_ + t2.minutes_;int sum_h = t1.hours_ + t2.hours_ + sum_m / 60;sum_m %= 60;return Time(sum_h, sum_m);
}
Time operator-(const Time& t1, const Time& t2)
{int sum_m = t1.minutes_ - t2.minutes_ + (t1.hours_ - t2.hours_) * 60;int sum_h = sum_m / 60;sum_m %= 60;return Time(sum_h, sum_m);
}
Time operator*(const Time& t1, double n)
{int sum_m = t1.hours_ * 60 * n + t1.minutes_ * n;return Time(sum_m / 60, sum_m % 60);
}
// 原友元
std::ostream& operator<<(std::ostream& os, const Time& t)
{os << t.hours_ << " hours, " << t.minutes_ << "minutes.";return os;
}
5. 重新编写Stonewt类(程序清单11.16和程序清单11.17),使它有一个状态成员,由该成员来控制对象应转换为英石格式、整数磅格式还是浮点磅格式。重载运<<运算符,使用它来替换show_stn()和show_lbs()方法。重载加法、减法和乘法运算符,以便可以对Stonewt值进行加、减、乘运算。编写一个使用所有类方法和友元的小程序来测试这个类。
答:
Stonewt.h头文件
#pragma once// 头文件
#include <iostream>// Stonewt类声明
class Stonewt
{
public:enum Style {STONE, POUNDS, FPOUNDS};
private:enum {Lbs_per_stn = 14};int stone;double pds_left;double pounds;Style style;
public:Stonewt();Stonewt(double lbs);Stonewt(int stn, double lbs);~Stonewt() { };void set_style(Style s);// 运算符重载Stonewt operator+(const Stonewt& s) const;Stonewt operator-(const Stonewt& s) const;Stonewt operator*(double n) const;// 友元friend std::ostream& operator<<(std::ostream& os, const Stonewt& s);
};
main5.cpp测试文件
// 头文件
#include "Stonewt.h"// using 声明
using std::cout;
using std::endl;int main()
{Stonewt incognito = 275;cout << "incognito: " << incognito << endl;Stonewt wolfe(287.5);cout << "wolfe: " << wolfe << endl;Stonewt taft(21, 8);cout << "taft: " << taft << endl;incognito = 276.8;cout << "incognito: " << incognito << endl;cout << "wolfe: " << wolfe * 2.3 << endl;taft = incognito + wolfe + 200;cout << "taft: " << taft << endl;wolfe.set_style(Stonewt::FPOUNDS);wolfe = wolfe * 2.3;cout << "wolfe: " << wolfe << endl;return 0;
}
Stonewt.cpp方法定义文件
// 头文件
#include "Stonewt.h"Stonewt::Stonewt()
{stone = pounds = pds_left = 0;style = STONE;
}Stonewt::Stonewt(double lbs)
{stone = int(lbs) / Lbs_per_stn;pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);pounds = lbs;style = FPOUNDS;
}Stonewt::Stonewt(int stn, double lbs)
{stone = stn;pds_left = lbs;pounds = stn * Lbs_per_stn + lbs;style = FPOUNDS;
}void Stonewt::set_style(Style s)
{style = s;
}// 运算符重载
Stonewt Stonewt::operator+(const Stonewt& s) const
{Stonewt tmp;tmp.pounds = pounds + s.pounds;tmp.stone = tmp.pounds / Lbs_per_stn;tmp.pds_left = (int)tmp.pounds % Lbs_per_stn + tmp.pounds - (int)tmp.pounds;tmp.style = this->style;return tmp;
}Stonewt Stonewt::operator-(const Stonewt& s) const
{Stonewt tmp;tmp.pounds = pounds - s.pounds;tmp.stone = tmp.pounds / Lbs_per_stn;tmp.pds_left = (int)tmp.pounds % Lbs_per_stn + tmp.pounds - int(tmp.pounds);tmp.style = this->style;return tmp;
}Stonewt Stonewt::operator*(double n) const
{Stonewt tmp;tmp.pounds = pounds * n;tmp.stone = tmp.pounds / Lbs_per_stn;tmp.pds_left = int(tmp.pounds) / Lbs_per_stn + tmp.pounds - (int)tmp.pounds;tmp.style = this->style;return tmp;
}// 友元
std::ostream& operator<<(std::ostream& os, const Stonewt& s)
{if (s.style == Stonewt::STONE){double st = s.stone + s.pds_left / Stonewt::Lbs_per_stn;os << st << "stone\n";}else if (s.style == Stonewt::POUNDS){os << s.pounds << "pounds\n";}else{os << s.stone << "stone, " << s.pds_left << "pounds\n";}return os;
}
6. 重新编写Stonewt类(程序清单11.16和程序清单11.17),重载6个关系运算符。运算对pounds成员进行比较,并返回一个布尔值。编写一个程序,他声明一个包含6个Stonewt对象的数组,并在数组声明中初始化前3个对象。然后使用循环来读取用于设置剩余的三个数组元素的值。接着报告最小的元素、最大的元素以及大于或等于11英石的元素的数量(最简单的方法是创建一个Stonewt对象,并将其初始化为11英石,然后将该对象同其他对象进行比较)。
答:
Stonewt1.h头文件
#pragma once// 头文件
#include <iostream>// Stonewt类声明
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& s) const;bool operator<=(const Stonewt& s) const;bool operator>(const Stonewt& s) const;bool operator>=(const Stonewt& s) const;bool operator==(const Stonewt& s) const;bool operator!=(const Stonewt& s) const;void show_lbs() const;void show_stn() const;
};
main6.cpp测试文件
// 头文件
#include "Stone1.h"// 符号常量
const int SIZE = 6;// using 声明
using std::cin;
using std::cout;
using std::endl;int main()
{Stonewt stone_arr[SIZE] = { 253.6, Stonewt(8, 0.35), Stonewt(23, 0) };double input;Stonewt eleven = Stonewt(11, 0.0);Stonewt max = stone_arr[0];Stonewt min = stone_arr[0];int num = 0;for (int i = 3; i < SIZE; ++i){cout << "enter the No." << i + 1 << "'s element info(int pounds): ";cin >> input;stone_arr[i] = Stonewt(input);while (cin.get() != '\n')continue;}for (int i = 0; i < SIZE; ++i){if (max < stone_arr[i]) max = stone_arr[i];if (min > stone_arr[i]) min = stone_arr[i];if (stone_arr[i] > eleven)++num;}cout << "The weight max: ";max.show_stn();cout << "\nThe weight min: ";min.show_stn();cout << "\nHeavy than eleven: " << num << endl;return 0;
}
Stonewt1.cpp方法定义文件
// 头文件
#include "Stone1.h"// using 声明
using std::cout;
using std::endl;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& s) const
{return pounds < s.pounds;
}
bool Stonewt::operator<=(const Stonewt& s) const
{return pounds <= s.pounds;
}
bool Stonewt::operator>(const Stonewt& s) const
{return pounds > s.pounds;}
bool Stonewt::operator>=(const Stonewt& s) const
{return pounds >= s.pounds;}
bool Stonewt::operator==(const Stonewt& s) const
{return pounds == s.pounds;}
bool Stonewt::operator!=(const Stonewt& s) const
{return pounds != s.pounds;
}void Stonewt::show_lbs() const
{cout << stone << "stone, " << pds_left << "pounds\n";
}
void Stonewt::show_stn() const
{cout << pounds << "pounds\n";
}
7. 按要求实现一个复数类(complex)…。
答:
complex.h头文件
#pragma once// 头文件
#include <iostream>// complex类声明
class complex
{
private:double real; // 实部double imaginary; // 虚部
public:complex(double a = 0, double b = 0); // 默认构造函数~complex(); // 析构函数// 运算符重载complex operator~() const;complex operator+(const complex& c) const;complex operator-(const complex& c) const;complex operator*(const complex& c) const;complex operator*(double n) const;// 友元friend complex operator*(double n, const complex& c) { return c * n; }friend std::ostream& operator<<(std::ostream& os, const complex& c);friend std::istream& operator>>(std::istream& is, complex& c);
};
main7.cpp测试文件
// 头文件
#include "complex.h"// using 声明
using std::cin;
using std::cout;
using std::endl;int main()
{complex a(3.0, 4.0);complex c;cout << "Enter a complex number (q to quit):\n";while (cin >> c){cout << "c is " << c << endl;cout << "complex conjugate is " << ~c << endl;cout << "a is " << a << endl;cout << "a + c is " << a + c << endl;cout << "a - c is " << a - c << endl;cout << "a * c is" << a * c << endl;cout << "2 * c is " << 2 * c << endl;cout << "Enter a complex number (q to quit):\n";}cout << "Done!\n";return 0;
}
complex.cpp方法定义文件
// 头文件
#include "complex.h"// using 声明
using std::cout;complex::complex(double a, double b) // 默认构造函数
{real = a;imaginary = b;
}complex::~complex() // 析构函数
{}// 运算符重载
complex complex::operator~() const
{return complex(real, -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);
}complex complex::operator*(const complex& c) const
{int a = real * c.real - imaginary * c.imaginary;int b = real * c.imaginary + imaginary * c.real;return complex(a, b);
}complex complex::operator*(double n) const
{return complex(real * n, imaginary * n);
}// 友元
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)
{cout << "real: ";if (!(is >> c.real))return is;cout << "imaginary: ";is >> c.imaginary;return is;
}
程序运行结果