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

2023-12-02 13:28
文章标签 c++ 使用 primerplus

本文主要是介绍《C++PrimerPlus》第11章 使用类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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代表1private: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); // 构造函数1Stonewt(double stn, double lbs); // 构造函数2Stonewt(); // 默认构造函数void Show_lbs() const;void Show_stns() const;operator double() const; // 转换函数1operator int() const; // 转换函数2 
};#endif

源代码main.cpp

#include "stonewt.h"using namespace std;int main() {Stonewt incognito = 275; // == Stonewt incognito(275)Stonewt wolfe(285.7); // 构造函数1Stonewt taft(21, 8); // 构造函数2incognito.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;
}

这篇关于《C++PrimerPlus》第11章 使用类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445514

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名