C++----------类的设计

  1. 二维点的表示(类设计)

    • 知识点讲解
      • 封装:将数据成员(xy坐标)设为private,这遵循了面向对象编程中的封装原则,防止外部代码随意修改类内部的数据,保证数据的安全性和完整性。只有通过类提供的公有成员函数(getXgetYsetXsetY)才能访问和修改数据。
      • 构造函数:提供了一个带默认参数的构造函数Point(double _x = 0, double _y = 0),这样既可以创建指定坐标的点,也能方便地创建原点。默认参数简化了代码,减少了重载构造函数的数量。
      • 访问器与修改器getXgetY函数被定义为const,意味着调用它们不会修改类对象的状态,这符合函数的语义,也能让这些函数用于const对象。setXsetY用于更新坐标值。
  2. 操作符重载

    • 知识点讲解
      • 加法操作符重载:通过Point operator+(const Point& p1, const Point& p2)重载+操作符,这使得代码书写更符合数学直觉,Point类对象能像内置数据类型一样相加。函数接收两个const引用参数,避免了不必要的对象复制,提高效率,并且保证传入的对象在函数内不会被修改。
      • 输出流操作符重载std::ostream& operator<<(std::ostream& os, const Point& p)重载<<操作符用于格式化输出Point对象。返回std::ostream&类型,以便能连续使用输出操作符,例如cout << p1 << " 和 " << p2,这遵循了流操作的链式调用风格。
  3. 有理数类设计

    • 知识点讲解
      • 数据成员与初始化Rational类有两个数据成员numerator(分子)和denominator(分母) 。构造函数Rational(int num = 0, int den = 1)通过默认参数支持创建整数形式的有理数,同时立即调用simplify函数对分数进行约分和规范符号,确保有理数始终以最简形式存在。
      • 约分与符号处理simplify函数利用std::gcd(求最大公约数函数,来自<algorithm>库)对分子分母约分,还会调整分母为正,让有理数的表示更加规范统一。
      • 加法操作符重载Rational operator+(const Rational& r) const重载加法操作符,按照分数加法规则计算新的分子分母,再构造并返回新的Rational对象。函数标记为const,因为它不会修改调用它的对象状态。
        在这里插入图片描述
  4. token扫描器类设计

    • 知识点讲解
      • 成员变量TokenScanner类有两个关键成员变量,input存储待扫描的字符串,pos记录当前扫描位置,它们控制着扫描流程。
      • 扫描逻辑nextToken函数通过移动pos跳过开头的空白字符,然后截取连续的非空白字符段作为一个token,实现了基本的词法扫描功能。这种逐步移动指针、截取子串的方式是文本处理类常见的做法。
      • 状态判断hasMoreTokens函数通过比较posinput的大小,快速判断是否还有剩余未扫描的token,方便控制循环扫描的流程。
  5. 将程序封装成类

    • 知识点讲解
      • 职责单一CircleAreaCalculator类专注于圆面积的计算这一单一职责,把相关的半径数据和计算逻辑封装在一起。遵循单一职责原则的类更容易维护、测试和扩展。
      • 构造函数与初始化:构造函数CircleAreaCalculator(double r)接收半径参数初始化radius,为后续计算面积做准备。这种在构造时初始化关键数据的方式很常见,保证对象创建后处于可用状态。
      • 常量成员函数calculateArea函数被定义为const,因为它只读取radius的值来计算面积,不修改类的任何成员变量,向调用者表明函数的“只读”特性,同时也允许该函数被const对象调用。

以下是更详细的代码示例,:

#include <iostream>
#include <algorithm>
#include <string>// 二维点的表示
class Point {
private:double x;double y;
public:// 构造函数,带默认参数Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}  // 访问器函数double getX() const { return x; }  double getY() const { return y; }  // 修改器函数void setX(double newX) { x = newX; }  void setY(double newY) { y = newY; }  
};// 操作符重载:加法
Point operator+(const Point& p1, const Point& p2) {return Point(p1.getX() + p2.getX(), p1.getY() + p2.getY());
}// 操作符重载:输出流
std::ostream& operator<<(std::ostream& os, const Point& p) {os << "(" << p.getX() << ", " << p.getY() << ")";return os;
}// 有理数类
class Rational {
private:int numerator;int denominator;// 约分和符号处理函数void simplify() {int gcd = std::gcd(numerator, denominator);numerator /= gcd;denominator /= gcd;if (denominator < 0) {numerator = -numerator;denominator = -denominator;}}
public:// 构造函数,带默认参数Rational(int num = 0, int den = 1) : numerator(num), denominator(den) {simplify();}  int getNumerator() const { return numerator; }int getDenominator() const { return denominator; }// 加法操作符重载Rational operator+(const Rational& r) const {int newNum = numerator * r.denominator + r.numerator * denominator;int newDen = denominator * r.denominator;return Rational(newNum, newDen);}
};// token扫描器类
class TokenScanner {
private:std::string input;size_t pos;
public:TokenScanner(const std::string& str) : input(str), pos(0) {}std::string nextToken() {while (pos < input.size() && std::isspace(input[pos])) {pos++;}if (pos >= input.size()) {return "";}size_t start = pos;while (pos < input.size() &&!std::isspace(input[pos])) {pos++;}return input.substr(start, pos - start);}bool hasMoreTokens() {return pos < input.size();}
};// 将程序封装成类:圆面积计算器
class CircleAreaCalculator {
private:double radius;
public:CircleAreaCalculator(double r) : radius(r) {}double calculateArea() const {return 3.14 * radius * radius;}
};int main() {// 二维点的使用Point p1(1.0, 2.0);Point p2(3.0, 4.0);Point sum = p1 + p2;std::cout << "p1: " << p1 << ", p2: " << p2 << ", sum: " << sum << std::endl;// 有理数的使用Rational r1(1, 2);Rational r2(1, 3);Rational sumR = r1 + r2;std::cout << r1.getNumerator() << "/" << r1.getDenominator() << " + " << r2.getNumerator() << "/" << r2.getDenominator() << " = " << sumR.getNumerator() << "/" << sumR.getDenominator() << std::endl;// token扫描器的使用std::string test = "hello world";TokenScanner scanner(test);while (scanner.hasMoreTokens()) {std::string token = scanner.nextToken();std::cout << "Token: " << token << std::endl;}// 圆面积计算器的使用CircleAreaCalculator calculator(5.0);double area = calculator.calculateArea();std::cout << "圆的面积: " << area << std::endl;return 0;
}

这段代码整合了多个类的设计与应用,展示了如何通过类来封装数据与功能,以及利用操作符重载让自定义类的使用更加自然流畅,同时还有文本扫描和简单几何计算功能的实现。

  1. 二维点的表示(类设计)
    • 类的定义
      • 首先,定义一个Point类来表示二维空间中的点。类中包含两个成员变量,分别表示xy坐标,以及相应的构造函数、访问器(getter)和修改器(setter)函数。
      class Point {
      private:double x;double y;
      public:Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}double getX() const { return x; }double getY() const { return y; }void setX(double newX) { x = newX; }void setY(double newY) { y = newY; }
      };
      
    • 使用示例
      • main函数或者其他函数中,可以创建Point类的对象并操作它。
      int main() {Point p(3.0, 4.0);std::cout << "点的坐标: (" << p.getX() << ", " << p.getY() << ")" << std::endl;return 0;
      }
      
  2. 操作符重载
    • 加法操作符重载
      • Point类重载+操作符,使得两个Point对象可以相加,结果是一个新的Point对象,其坐标分别为两个原始点对应坐标之和。
      Point operator+(const Point& p1, const Point& p2) {return Point(p1.getX() + p2.getX(), p1.getY() + p2.getY());
      }
      
      • 使用示例:
      int main() {Point p1(1.0, 2.0);Point p2(3.0, 4.0);Point sum = p1 + p2;std::cout << "相加后的点坐标: (" << sum.getX() << ", " << sum.getY() << ")" << std::endl;return 0;
      }
      
    • 输出流操作符重载
      • 重载<<操作符,以便能够直接将Point对象输出到标准输出流。
      std::ostream& operator<<(std::ostream& os, const Point& p) {os << "(" << p.getX() << ", " << p.getY() << ")";return os;
      }
      
      • 使用示例:
      int main() {Point p(5.0, 6.0);std::cout << "点: " << p << std::endl;return 0;
      }
      
  3. 有理数类设计
    • 类定义
      • 有理数由分子和分母组成,在类中需要考虑约分、符号处理等问题。
      class Rational {
      private:int numerator;int denominator;void simplify() {int gcd = std::gcd(numerator, denominator);numerator /= gcd;denominator /= gcd;if (denominator < 0) {numerator = -numerator;denominator = -denominator;}}
      public:Rational(int num = 0, int den = 1) : numerator(num), denominator(den) {simplify();}int getNumerator() const { return numerator; }int getDenominator() const { return denominator; }Rational operator+(const Rational& r) const {int newNum = numerator * r.denominator + r.numerator * denominator;int newDen = denominator * r.denominator;return Rational(newNum, newDen);}
      };
      
    • 使用示例
      • 创建有理数对象并进行加法运算。
      int main() {Rational r1(1, 2);Rational r2(1, 3);Rational sum = r1 + r2;std::cout << "两有理数相加结果: " << sum.getNumerator() << "/" << sum.getDenominator() << std::endl;return 0;
      }
      
  4. token扫描器类设计
    • 类定义与功能概述
      • token扫描器用于将输入的字符串分割成一个个有意义的token。类中包含输入字符串、当前扫描位置等成员变量,以及扫描下一个token、判断是否结束等成员函数。
      class TokenScanner {
      private:std::string input;size_t pos;
      public:TokenScanner(const std::string& str) : input(str), pos(0) {}std::string nextToken() {while (pos < input.size() && std::isspace(input[pos])) {pos++;}if (pos >= input.size()) {return "";}size_t start = pos;while (pos < input.size() &&!std::isspace(input[pos])) {pos++;}return input.substr(start, pos - start);}bool hasMoreTokens() {return pos < input.size();}
      };
      
    • 使用示例
      • 输入一个字符串,通过扫描器获取其中的token。
      int main() {std::string test = "hello world";TokenScanner scanner(test);while (scanner.hasMoreTokens()) {std::string token = scanner.nextToken();std::cout << "Token: " << token << std::endl;}return 0;
      }
      
  5. 将程序封装成类
    • 整体思路
      • 以一个简单的数学计算程序为例,把计算逻辑封装到一个类中。假设要封装一个计算圆面积的程序,类中包含半径成员变量、计算面积的函数等。
      class CircleAreaCalculator {
      private:double radius;
      public:CircleAreaCalculator(double r) : radius(r) {}double calculateArea() const {return 3.14 * radius * radius;}
      };
      
    • 使用示例
      • 创建类的对象,调用计算函数。
      int main() {CircleAreaCalculator calculator(5.0);double area = calculator.calculateArea();std::cout << "圆的面积: " << area << std::endl;return 0;
      }
      

通过以上设计,可以将不同的功能需求通过类的形式进行良好的组织,提高代码的模块化、可复用性和可读性。
在这里插入图片描述

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

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

相关文章

教育行业 UI 设计基础篇:简洁直观的风格打造

在当今数字化时代&#xff0c;教育行业的线上平台如雨后春笋般涌现&#xff0c;而 UI 设计作为用户与教育产品交互的重要桥梁&#xff0c;其重要性不言而喻。对于教育行业而言&#xff0c;简洁直观的 UI 风格能够极大地提升用户体验&#xff0c;帮助学习者更高效地获取知识。 …

分布式协同 - 分布式事务_2PC 3PC解决方案

文章目录 导图Pre2PC&#xff08;Two-Phase Commit&#xff09;协议准备阶段提交阶段情况 1&#xff1a;只要有一个事务参与者反馈未就绪&#xff08;no ready&#xff09;&#xff0c;事务协调者就会回滚事务情况 2&#xff1a;当所有事务参与者均反馈就绪&#xff08;ready&a…

GFPS扩展技术原理(七)-音频切换消息流

音频切换消息流 Seeker和Provider通过消息流来同步音频切换能力&#xff0c;触发连接做切换&#xff0c;获取或设置音频切换偏好&#xff0c;通知连接状态等等。为此专门定义了音频切换消息流Message Group 为0x07&#xff0c;Message codes如下&#xff1a; MAC of Audio s…

实现 QTreeWidget 中子节点勾选状态的递归更新功能只影响跟节点的状态父节点状态不受影响

在 Qt 开发中&#xff0c;QTreeWidget 提供了树形结构的显示和交互功能。为了实现某个子节点勾选或取消勾选时&#xff0c;只影响当前节点及其子节点的状态&#xff0c;同时递归更新父节点的状态以正确显示 Qt::PartiallyChecked 或 Qt::Checked&#xff0c;我们可以借助 Qt 的…

计算机图形学知识点汇总

一、计算机图形学定义与内容 1.图形 图形分为“图”和“形”两部分。 其中&#xff0c;“形”指形体或形状&#xff0c;存在于客观世界和虚拟世界&#xff0c;它的本质是“表示”&#xff1b;而图则是包含几何信息与属性信息的点、线等基本图元构成的画面&#xff0c;用于表达…

Yolo11改策略:卷积改进|SAC,提升模型对小目标和遮挡目标的检测性能|即插即用

摘要 一、论文介绍 本文参考的论文主要介绍了DetectoRS模型&#xff0c;一个高性能的目标检测模型。DetectoRS通过引入递归特征金字塔&#xff08;RFP&#xff09;和可切换空洞卷积&#xff08;SAC&#xff09;两大创新点&#xff0c;显著提升了目标检测的精度。尽管原文并未…

Y3编辑器教程8:资源管理器与存档、防作弊设置

文章目录 一、资源管理器简介1.1 界面介绍1.2 资源商店1.3 AI专区1.3.1 AI文生图1.3.2 AI图生图1.3.3 立绘头像 二、导入导出2.1 文件格式2.2 模型导入2.2.1 模型制作后导出2.2.2 模型文件导入Y3编辑器2.2.3 Y3编辑器角色、装饰物模型要求 2.3 纹理导入2.4 材质贴图2.4.1 材质支…

【联动】【MSS】【AF】

【联动】【MSS】【AF】 一、版本要求 AF&#xff1a;不低于8.0.7&#xff1b;AF8.0.7R2不支持接入 二、接入配置 2.1、AF配置 对于AF8.0.13版本及以上&#xff0c;登录WEB控制台&#xff0c;点击[下一代安全防护体系] -> [云网联动] -> [云网接入设置]&#xff0c;然…

攻防世界 cookie

开启场景 Cookie&#xff08;HTTP cookie&#xff09;是一种存储在用户计算机上的小型文本文件。它由网站通过用户的浏览器在用户访问网站时创建&#xff0c;并存储一些用于跟踪和识别用户的信息。Cookie 主要用于在网站和浏览器之间传递数据&#xff0c;以便网站可以根据用户的…

STM32-笔记11-手写带操作系统的延时函数

1、为什么带操作系统的延时函数&#xff0c;和笔记10上的延时函数不能使用同一种&#xff1f; 因为笔记10的延时函数在每次调用的时候&#xff0c;会一直开关定时器&#xff0c;而在FreeRTOS操作系统中&#xff0c;SysTick定时器当作时基使用。 时基是一个时间显示的基本单位。…

JWT令牌与微服务

1. 什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种开放标准(RFC 7519)&#xff0c;它定义了一种紧凑且自包含的方式&#xff0c;用于作为JSON对象在各方之间安全地传输信息。JWT通常用于身份验证和信息交换。 以下是JWT的一些关键特性&#xff1a; 紧凑&#xff…

代码随想录Day37 动态规划:完全背包理论基础,518.零钱兑换II,本周小结动态规划,377. 组合总和 Ⅳ,70. 爬楼梯(进阶版)。

1.完全背包理论基础 思路 完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 完…

【多时段】含sop的配电网重构【含分布式电源】【已更新视频讲解】

1 主要内容 之前分享了很多配电网重构的程序&#xff0c;每个程序针对场景限定性比较大&#xff0c;程序初学者修改起来难度较大&#xff0c;本次分享一个基础程序&#xff0c;针对含sop的配电网重构模型&#xff0c;含风电和光伏&#xff0c;优化了33节点网络电压合理性&…

查看php已安装扩展命令

在powershell中查看完整的拓展 php -m 指定搜索某几个拓展 php -m | Select-String -Pattern "xml"

YOLOv11 引入高效的可变形卷积网络 DCNv4 | 重新思考用于视觉应用的动态和稀疏算子

我们介绍了可变形卷积v4(DCNv4),这是一种为广泛的视觉应用设计的高效且有效的算子。DCNv4通过以下两项关键改进解决了其前身DCNv3的局限性: 在空间聚合中移除softmax归一化,以增强其动态特性和表达能力。优化内存访问,减少冗余操作以提高速度。这些改进使得DCNv4相比DCNv…

vue 基础学习

一、ref 和reactive 区别 问题&#xff1a;发生跨域问题 Access to script at file:///Users/new/Desktop/webroot/vue/vue.esm-browser.js from origin null has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: chrome, chrom…

AIA - IMSIC之二(附IMSIC处理流程图)

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 ​​​​​​​通过IMSIC接收外部中断的CSR 软件通过《AIA - 新增的CSR》描述的CSR来访问IMSIC。 machine level 的 CSR 与 IMSIC 的 machine level interrupt file 可相互互动;而 supervisor level 的 CSR…

光谱相机的工作原理

光谱相机的工作原理主要基于不同物质对不同波长光的吸收、反射和透射特性存在差异&#xff0c;以下是其具体工作过程&#xff1a; 一、光的收集 目标物体在光源照射下&#xff0c;其表面会对光产生吸收、反射和透射等相互作用。光谱相机的光学系统&#xff08;如透镜、反射镜…

Kafka可视化工具 Offset Explorer (以前叫Kafka Tool)

数据的存储是基于 主题&#xff08;Topic&#xff09; 和 分区&#xff08;Partition&#xff09; 的 Kafka是一个高可靠性的分布式消息系统&#xff0c;广泛应用于大规模数据处理和实时, 为了更方便地管理和监控Kafka集群&#xff0c;开发人员和运维人员经常需要使用可视化工具…

TLDR:终端命令的简洁百科全书

TLDR&#xff0c;全称 “Too Long, Don’t Read”&#xff0c;是一款特别实用的终端命令百科全书工具。通过 TLDR&#xff0c;您可以快速查找到常用命令的使用方法&#xff0c;避免繁琐冗长的官方文档&#xff0c;让日常工作更加高效。 为什么选择 TLDR&#xff1f; 简单易用&…