《C++PrimerPlus》第11章 使用类

news2024/11/20 14:29:37

11.1 运算符重载

11.2 计算时间:一个运算符重载示例

运算符重载示例(计算时间)

头文件mytime0.h

#ifndef  __MYTIME0__H__
#define __MYTIME0__H__
#include <iostream>
using namespace std;

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 mult) const; // 乘法
		friend Time operator*(double mult, const Time &t); // 乘法(友元函数)
		friend ostream &operator<<(ostream &os, const Time &t); // cout输出(友元函数)
};

#endif

源代码mytime0.cpp

#include "mytime0.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 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 = hours * 60 + minutes;
	tot2 = t.hours * 60 + t.minutes;
	diff.hours = (tot1 - tot2) / 60;
	diff.minutes = (tot1 - tot2) % 60;
	return diff;
}

Time Time::operator*(double mult) const {
	Time result;
	long totalminutes = hours * 60 * mult + minutes * mult;
	result.hours = totalminutes / 60;
	result.minutes = totalminutes % 60;
	return result;
}

Time operator*(double mult, const Time &t) {
	Time result;
	long totalminutes = t.hours * 60 * mult + t.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." << endl;
	return os;
}

源代码usetime0.cpp

#include "mytime0.h"

int main() {
	Time coding(4, 35);
	Time fixing(2, 47);
	cout << "coding time = ";
	cout << coding;
	cout << "fixing time = ";
	cout << fixing;

	Time total = coding + fixing; // 运算符+重载(运算符表示法)
	cout << total;
	Time Planning = coding.operator+(fixing); // 运算符+重载(函数表示法)
	cout << Planning;

	Time diff = coding - fixing; // 运算符-重载
	cout << diff;
	Time adjusted = coding * 1.5; // 运算符*重载
	cout << adjusted;

	Time adjusted1 = 1.5 * coding; // 运算符*重载(友元函数)
	cout << adjusted1;

	cout << "************************" << endl;
	cout << coding << fixing << endl; // cout连续输出

	return 0;
}

11.3 友元

11.4 重载运算符:作为成员函数还是非成员函数

11.5 再谈重载:一个矢量类

醉汉漫步问题(走几步可以离原点大于指定的距离)

头文件vector.h

#ifndef __VECTOR__H__
#define __VECTOR__H__
#include <iostream>
using namespace std;

namespace VECTOR {
	class Vector {
	public:
		enum Mode{RECT, POL}; // 直角坐标RECT代表0,极坐标POL代表1
	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); // 恢复默认值
		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 ostream &operator<<(ostream &os, const Vector &v); // <<运算符重载
	};
}

#endif

源代码main.cpp

#include "vector.h"
#include <cstdlib>
#include <ctime>

using namespace std;
using namespace VECTOR;

int main() {
	double target; // 目标走多远
	double dstep; // 一步走多远
	Vector result(0.0,0.0); // 使用构造函数创建对象
	double direction; // 方向
	srand(time(NULL)); // 使用系统时间来初始化种子(种子不变则随机数不变)
	Vector step; // 使用默认构造函数
	unsigned long steps = 0; // 记录走了几步

	cout << "Enter target distance(q to quit): ";
	while (cin >> target) {
		cout << "Enter the step length: ";
		if (!(cin >> dstep)) break;
		while (result.magval() < target) {
			direction = rand() % 360; // 0~359度的随机方向
			step.reset(dstep, direction, Vector::POL); // 极坐标
			result = result + step;
			steps++;
		}
		cout << "After " << steps << " step, achieve the target distance." << endl;
		cout << result; // 打印坐标
		result.polar_mode(); // 转换为极坐标
		cout << result;
		cout << endl;
		steps = 0;
		result.reset(0.0, 0.0); // 复位结果
		cout << "Enter target distance(q to quit): ";
	}
	cout << "Bye!" << endl;
	return 0;
}

源代码vector.cpp

#include "vector.h"
#include <cmath>

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 << "Error" << endl;
			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 << "Error" << endl;
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}
	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 << endl;
		}
		else if (v.mode == Vector::POL) {
			os << "mag, ang = " << v.mag << ", " << v.ang << endl;
		}
		else {
			os << "Invalid mode." << endl;
		}
		return os;
	}
}

11.6 类的自动转换和强制类型转换

类的类型转换示例(磅和英石的转换)

头文件stonewt.h

#ifndef __STONEWT__H__
#define __STONEWT__H__
#include <iostream>

using namespace std;

class Stonewt {
private:
	enum{Lbs_per_stn = 14}; // 用枚举方式创建常量
	int stone;
	double pds_left;
	double pounds;
public:
	Stonewt(double lbs); // 构造函数1
	Stonewt(double stn, double lbs); // 构造函数2
	Stonewt(); // 默认构造函数
	void Show_lbs() const;
	void Show_stns() const;
	operator double() const; // 转换函数1
	operator int() const; // 转换函数2 
};

#endif

源代码main.cpp

#include "stonewt.h"

using namespace std;

int main() {
	Stonewt incognito = 275; // == Stonewt incognito(275)
	Stonewt wolfe(285.7); // 构造函数1
	Stonewt taft(21, 8); // 构造函数2

	incognito.Show_stns(); 
	wolfe.Show_stns();
	taft.Show_stns();

	cout << "*************************" << endl;
	incognito = 276.8; // 类的自动的类型转换(隐式转换)
	incognito.Show_stns();

	Stonewt poppins(9, 2.8);
	double p_wt = poppins; // 使用转换函数把Stonewt类转换成double值(隐式调用)
	cout << "poppins = " << p_wt << endl;
	int weight = poppins;
	cout << "poppins = " << weight << endl;
	cout << "poppins = " << int(poppins) << endl; // 显式调用
	return 0;
}

源代码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(double stn, double lbs) {
	stone = stn;
	pds_left = lbs;
	pounds = stn * Lbs_per_stn + lbs;
}

Stonewt::Stonewt() {
	stone = pds_left = pounds = 0;
}

void Stonewt::Show_stns() const {
	cout << stone << " stones, " << pds_left << " pounds." << endl;
}

void Stonewt::Show_lbs() const {
	cout << pounds << " pounds." << endl;
}

Stonewt::operator int() const {
	return int (pounds + 0.5); // 四舍五入
}

Stonewt::operator double() const {
	return pounds;
}

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

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

相关文章

【ECCV 2022】《Transformers as Meta-learners for Implicit Neural Representations》

文章目录 一、动机二、相关工作三、方法四、实验部分五、Does the INR Exploit Data Structures?六、结论 一、动机 \quad 与像素、体素和网格等离散数据表示相比&#xff0c;INRs不需要依赖于分辨率的二次或三次存储。它们的表示能力并不依赖于网格分辨率&#xff0c;而是依赖…

《ChatGPT实操应用大全》探索无限可能

&#x1f5e3;️探索ChatGPT&#xff0c;开启无限可能&#x1f680; 文末有免费送书福利&#xff01;&#xff01;&#xff01; ChatGPT是人类有史以来最伟大的发明。他能写作、绘画、翻译、看病、做菜、编程、数据分析、制作视频、解高等数学题…&#xff0c;他会的技能…

网站上https协议,nginx配置SSL,443端口

nginx配置ssl 要给自己的网站上ssl证书&#xff0c;使用https协议。首先你需要有证书文件&#xff0c;这个文件是你买的服务&#xff0c;买过之后别人会给你。 就是这样的文件&#xff1a; 然后你就把文件上传到服务器的一个位置&#xff0c;你记住这个位置&#xff0c;后面配…

树莓派3B+ PCB叠层设计

板子废了&#xff0c;用电磨切了下&#xff0c;看看是什么叠层。 由于有BCM43455 WIFI芯片&#xff0c;这个是0.3ball 0.4pitch&#xff0c;肯定是要用盲孔布线的。 然后根据这个切面看&#xff0c;板子是6层的&#xff0c;外层内层铜厚应该是一样的 1-2层介质特别薄竟然<1o…

unicloud云函数url化后,客户端通过url地址向云函数发送数据流并传递到云存储中

在不久前录制过这样一门课程&#xff0c;使用uniapp生态开发API接口&#xff0c;通过这套课程&#xff0c;你不需要后后端Java、Python、PHP等后端语言&#xff0c;你只需要用前端的知识就可以构建这样一套API接口&#xff0c;而且使用uniapp生态开发接口更简单高效&#xff0c…

共享单车停放(简单的struct结构运用)

本来不想写这题的&#xff0c;但是想想最近沉迷玩雨世界&#xff0c;班长又问我这题&#xff0c;就草草写了一下 代码如下&#xff1a; #include<stdio.h> #include<math.h> struct parking{int distance;int remain;int speed;int time;int jud; }parking[50]; …

2022年1月14日 Go生态洞察:Go 1.18 新教程探索

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

java+springboot停车场小区车库租赁预订系统ssm+jsp

该平台为客户和业主提供等信息服务平台的运营方&#xff0c;管理方&#xff0c;如何通过车库平台建立实现优化管理的方法提供参考。能够实现在一个相对广阔的地域内&#xff08;例如一座城市)的多个停车场的随意停车。管理平台会统一调度车位资源&#xff0c;自动进行交易结算。…

12月01日,每日信息差//阿里国际发布3款AI设计生态工具//美团买菜升级为“小象超市”//外国人永居证换新、6国游客免签来华

_灵感 &#x1f396; 阿里国际发布3款AI设计生态工具 &#x1f384; AITO问界系列11月交付新车18827辆 &#x1f30d; 美团买菜升级为“小象超市” &#x1f30b; 全球首个金融风控大模型国际标准出炉&#xff0c;由腾讯牵头制定 &#x1f381; 支付宝&#xff1a;支持外国人…

剪辑必备AI去水印神器,手把手教你轻松消除图片水印

当我们的剪辑制作过程中&#xff0c;前期需要准备图片或视频素材&#xff0c;水印往往成为了我们首要解决的难题。 幸运的是&#xff0c;今天我为大家介绍一款在线AI去水印神器--水印云。 水印云是一个的在线去除图片水印工具。仅需三步&#xff0c;即可使用强大的 AI 技术从图…

latex表格中内容过多如何换行【已解决】

最近在写论文的时候放了一个表格&#xff0c;但是表格看起来特别大&#xff0c;因为想让某些内容多的单元格完成换行操作 首先在main.tex引入makecell包 \usepackage{makecell} 然后回到表格找到你想换行的单元格&#xff0c;把\makecell{}加进去&#xff0c;然后在需要换行的…

人活着到底是为了什么?

​ 最近在思考一个问题&#xff0c;人活着到底是为了什么&#xff1f;活着的意义是什么&#xff1f; 每天朝九晚六&#xff0c;忙忙碌碌&#xff0c;如同行尸走肉一般&#xff0c;日复一日&#xff0c;年复一年的重复着同样的生活&#xff0c;到底是为了什么&#xff0c;能不…

Python面向对象练习

Python面向对象练习 class Enty:blood100name""atackvalue100team0domain[1] #1,land 2 airdef setTeam(self,team0):self.teamteamdef atack(self,Enty):if self.teamEnty.team:print("不能向盟军开火")self.info()passelse :# print(self.domain)ss…

7.3 Windows驱动开发:内核监视LoadImage映像回调

在笔者上一篇文章《内核注册并监控对象回调》介绍了如何运用ObRegisterCallbacks注册进程与线程回调&#xff0c;并通过该回调实现了拦截指定进行运行的效果&#xff0c;本章LyShark将带大家继续探索一个新的回调注册函数&#xff0c;PsSetLoadImageNotifyRoutine常用于注册Loa…

2023年第十二届数学建模国际赛小美赛A题太阳黑子预测求解分析

2023年第十二届数学建模国际赛小美赛 A题 太阳黑子预测 原题再现&#xff1a; 太阳黑子是太阳光球上的一种现象&#xff0c;表现为比周围区域暗的暂时斑点。它们是由抑制对流的磁通量浓度引起的表面温度降低区域。太阳黑子出现在活跃区域内&#xff0c;通常成对出现&#xff…

【VerilogVCS仿真_2023.11.15】

HDL&#xff1a;硬件描述语言&#xff0c;并发&#xff0c;时序RTL&#xff1a;寄存器传输级语言 Verilog和VHDL的区别&#xff1a;VHDL侧重于系统级描述——系统级设计人员所采用&#xff0c;Verilog侧重于模块行为的抽象描述——电路级设计人员 前端&#xff1a;系统级、算法…

[数据结构]深入浅出讲解二叉树-平衡二叉树-左右旋转

树是一种数据结构&#xff0c;单位为Node(节点)。不同于链表的直线排列&#xff0c;树呈现一种自上而下的分层排序规则。 树->数据结构&#xff1a; 单元为Node(节点)->当这样的节点多了 就可以关联出不同的形态 一个父节点有一个左子节点&#xff0c;有…

11.31链表,之前的数据结构(未完,饼)

根据输入序列建立二叉树 链表 回顾一下二分面积最小 一些性质题回顾 哈夫曼树构建 第十一周——哈夫曼树 5 1 2 2 5 9 37 桶排序 #include <iostream> #include <vector> #include <algorithm> #include<stack> #include<queue> #includ…

软件工程 - 第8章 面向对象建模 - 2 静态建模

静态建模&#xff08;类和对象建模&#xff09; 类和对象模型的基本模型元素有类、对象以及它们之间的关系。系统中的类和对象模型描述了系统的静态结构&#xff0c;在UML中用类图和对象图来表示。 类图由系统中使用的类以及它们之间的关系组成。类之间的关系有关联、依赖、泛…

Linux MIPI 调试中常见的问题

一、概述 做嵌入式工作的小伙伴知道&#xff0c;有时候程序编写没有调试过程中费时&#xff0c;之间笔记里有 MIPI 摄像头驱动开发的过程&#xff0c;有需要的小伙伴可以参考&#xff1a;Linux RN6752 驱动编写。而我也是第一次琢磨 MIPI 协议&#xff0c;其中有很多不明白的地…