《C++ Primer Plus》第十一章复习题和编程练习

这里写目录标题

  • 一、复习题
  • 二、编程练习

一、复习题

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;
}

程序运行结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/16077.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Imperva 导致的ORAbase 乱码

DBCA Failing Because Of Garbage Characters In ORACLE_BASE Variable (Doc ID 2947963.1)​编辑To Bottom In this Document Symptoms Changes Cause Solution APPLIES TO: Oracle Database Configuration Assistant - Version 19.14.0.0.0 and later Oracle Database - E…

本地镜像文件怎么导入docker desktop

docker tag d1134b7b2d5a new_repo:new_tag

PageHelper分页

文章目录 PageHelper分页ThreadLocalMap和ThreadLocal执行完PageHelper.startPage之后&#xff0c;分页参数存储到哪里了&#xff1f;Page和List的关系&#xff1f;PageInterceptor分页拦截器的作用&#xff1f;PageInfo的作用与结构&#xff1f;最后看下引入的pagehelper分页依…

YoloV1模型

You Only Look Once 文章目录 You Only Look Once置信度定义类别条件概率NMSnp.maxmiumnp.argsort() Yolov1直接采用网络特征输出&#xff0c;实现置信度预测、分类、边界框回归&#xff1b; 核心内容总结&#xff1a; 输入图像划分为 S S 网格。如果对象的中心落入网格单元中…

linux 安装chrome浏览器

一、下载安装包 下载地址&#xff1a;https://download.csdn.net/download/k0307x1990y/89349171 二、安装流程 [rootlocalhost ~]# rpm -ivh *.rpm [rootlocalhost ~]# yum -y localinstall google-chrome-stable_current_x86_64.rpm [rootlocalhost ~]# 三、修改配置文件…

Vxe UI 表单设计器、零代码平台

vxe-pc-ui Vxe UI 表单设计器、零代码表单设计器 安装 Vxe UI PC端组件库 官方文档 查看 github、gitee // ...import VxeUI from vxe-pc-uiimport vxe-pc-ui/lib/style.css// ...// ...createApp(App).use(VxeUI).mount(#app)// ...使用 vxe-form-design 设计器组件 vxe-fo…

【安装笔记-20240523-Windows-安装测试 ShareX】

安装笔记-系列文章目录 安装笔记-20240523-Windows-安装测试 ShareX 文章目录 安装笔记-系列文章目录安装笔记-20240523-Windows-安装测试 ShareX 前言一、软件介绍名称&#xff1a;ShareX主页官方介绍 二、安装步骤测试版本&#xff1a;16.1.0下载链接功能界面 三、应用场景屏…

QML的Image 路径问题(source)

四种路径格式 在 QML 中&#xff0c;当你使用 Image 元素的 source 属性来指定一个图片的路径时&#xff0c;有几种不同的方式可以指定这个路径&#xff0c;每种方式都有其特定的用途和上下文。 相对路径&#xff1a; QML 文件和一个名为 close.png 的图片在同一目录下&#x…

Spring:面向切面(AOP)

1. 代理模式 二十三种设计模式中的一种&#xff0c;属于结构型模式。它的作用就是通过提供一个代理类&#xff0c;让我们在调用目标方法的时候&#xff0c;不再是直接对目标方法进行调用&#xff0c;而是通过代理类**间接**调用。让不属于目标方法核心逻辑的代码从目标方法中剥…

【热门话题】Debian常用命令指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Debian常用命令指南引言1. 文件与目录操作lscdmkdirrmcpmv 2. 包管理aptdpkg 3.…

minaActivatorA12+物主锁完美解信号,可登iCloud,有消息通知,支持iOS17.5.1+

原创 IOS福利部落 IOS福利部落 2024-05-26 19:35 福建 Mina Activator A12是一款绕过物主锁界面的解锁工具&#xff0c;可以激活所有iPhone恢复信号&#xff0c;并且支持插卡接打电话、收发短信、4G流量上网&#xff0c;支持iCloud登录&#xff0c;有消息通知&#xff0c;支持i…

sklearn实现线性回归

sklearn实现线性回归 一、数据集介绍二、使用sklearn实现线性回归一、数据集介绍 本案例使用女性身高体重数据集,数据集如下图所示: 可以看到,数据集有15行2列。 二、使用sklearn实现线性回归 sklearn中的线性模型模块是linear_model。这里使用linear_model下的普通线性…

【Linux】-Redis安装部署[15]

目录 简介 安装 1、配置EPEL仓库 2、安装redis 3、启动redis 4、放行防火墙&#xff0c;redis使用端口6379 5、进入redis服务 简介 redis是一个开源、使用C语言编写的、支持网络互交的、可基于内存也可持久化的Key-Value数据库。redis的特点就是&#xff1a;快&#xf…

安全设计 | CISA:构建默认安全的软件,软件安全设计的未来之路

软件制造商在产品设计和开发过程中应采取安全设计原则和方法&#xff0c;以减少网络安全风险&#xff0c;并转变责任重心&#xff0c;使产品在设计时就内置安全特性&#xff0c;而不是依赖于后期的补丁和修复。为此CISA发布了《软件安全设计的原则和方法》&#xff0c;帮助软件…

python如何把字符串变成小写字母

Python中&#xff0c;将字符串中的字母转换成小写字母&#xff0c;字符串变量提供了2种方法&#xff0c;分别是title()、lower()。 Python title()方法 title()方法用于将字符串中每个单词的首字母转为大写&#xff0c;其他字母全部转为小写&#xff0c;转换完成后&#xff0…

如何在go语言中调用c语言代码

1.安装c语言编译器 要使用cgo&#xff0c;需要安装c语言编译器 gcc 2.检查CGO_ENABLED时候开启 使用以下命令查看&#xff1a; go env CGO_ENABLED 如果go env CGO_ENABLED被禁用(为0),需要将其设置为开启(为1) 3.编写c语言程序&#xff0c;并用go语言调用c语言程序 1&#xff…

AIGC 005-Dreambooth定制化生成,微调文本到图像的扩散模型!

AIGC 005-Dreambooth定制化生成&#xff0c;微调文本到图像的扩散模型&#xff01; 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 DreamBooth 论文 (DreamBooth: Fine-Tuning Text-to-Image Diffusion Models for Subject-Driven Generation) 提出了一种新颖的技术&#x…

【开源】大学生竞赛管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、系统介绍 学生管理模块 教师管理模块 竞赛信息模块 竞赛报名模块 二、系统截图 三、核心代码 一、系统介绍 基于Vue.js和SpringBoot的大学生竞赛管理系统&#xff0c;分为管理后台和用户网页端&#xff0c;可以给管理员、学生和教师角色使用&#xff0c;包括学…