《C++高级编程》读书笔记(四:设计专业的C++程序)

news2025/2/25 9:48:55

1、参考引用

  • C++高级编程(第4版,C++17标准)马克·葛瑞格尔

2、建议先看《21天学通C++》 这本书入门,笔记链接如下

  • 21天学通C++读书笔记(文章链接汇总)

1. 程序设计概述

  • 在启动新程序(或已有程序的新功能)时,第一步是分析需求
    • 分析阶段的重要输出是 “功能需求” 文档:描述新代码段到底要做什么,但它不解释如何做
    • 需求分析后,也可能得到 “非功能需求” 文档:其中描述最终系统是什么,而非做什么。非功能需求的例子有:系统必须是安全的、可扩展的,还能满足特定性能标准等
  • 第二步启动项目的设计阶段程序设计(或软件设计)是为了满足程序的所有功能和非功能需求而实现的结构规范
  • 大多数设计文档主要包括两个部分
    • (1) 将总的程序分为子系统,包括子系统之间的界面和依赖关系、子系统之间的数据流、每个子系统的输入输出和通用线程模型
    • (2) 每个子系统的详情,包括类的细分、类的层次结构、数据结构、算法、具体的线程模型和错误处理的细节

    设计文档通常包括图和表格,以显示子系统交互关系和类层次关系

2. 程序设计的重要性

  • 在编写代码之前进行规范的设计,有助于判断如何将所有内容组合在一起。程序的设计显示了程序子系统之间的关系和配合方式,以满足软件的需求。如果没有设计规划,可能会漏掉子系统之间的联系、重用或共享信息,以及失去用最简单方法完成任务的可能性。如果没有 “设计宏图”,可能会在某个实现细节上钻牛角尖,以至于忘记整体结构和目标

3. C++ 设计的两个原则

3.1 抽象

  • 关键在于将接口与实现分开
  • 抽象的作用
    • 可使用代码而不必了解底层的实现。在此有一个简单示例,程序可调用在 <cmath> 头文件中声明的 sqrt() 函数,而不需要知道这个函数使用什么算法求平方根。实际上,平方根计算的底层实现可能因库版本而异:但只要接口不变,函数调用就可以照常运行
    • 抽象原则也可以扩展到类:可使用 ostream 类的 cout 对象将数据传输到标准输出,不需要知道 cout 如何将文本输出到屏幕,只需了解公有接口
  • 在设计中使用抽象
    • 应该设计函数和类,使自己和其他程序员可以使用它们,而不需要知道(或依赖)底层的实现

3.2 重用

  • 重用的设计思想适用于自己编写和使用的代码,应该设计程序,以重用类、算法和数据结构
  • 在 C++ 中,模板是一种编写多用途代码的语言技术
    // 可用于任何二维棋盘游戏的 泛型游戏棋盘类
    template <typename PieceType>
    class GameBoard {
    public:
        void setPieceAt(size_t x, size_t y, PieceType *piece);
        PieceType *getPieceAt(size_t x, size_t y);
        bool isEmpty(size_t x, size_t y) const;
    private:
        ...
    }
    

4. 重用代码

4.1 关于术语的说明

  • 有三种可重用的代码

    • 过去编写的代码
    • 同事编写的代码
    • 当前组织或公司以外的第三方编写的代码
  • 所使用的代码可通过以下几种方式来构建

    • 独立的函数或类:当重用自己或同事的代码时,通常会遇到这种类型
    • 库:库是用于完成特定任务 (例如解析 XML) 或者针对特定领域 (如密码系统) 的代码集合。在库中经常可以找到其他许多功能,如线程和同步支持、网络和图像
    • 框架:框架是代码的集合,围绕框架设计程序。例如,微软基础类 (Microsoft FoundationClasses,MFC) 提供了在 Microsoft Windows 中创建图形用户界面应用程序的框架。框架通常指定了程序的结构
  • 应用程序编程接口(API)是另一个经常出现的术语。API 是库或代码为特定目的提供的接口。例如,程序员经常会提到套接字 API,这指的是套接字联网库的公开接口,而不是库本身

  • 如果想要用 C++ 在 Microsot Windows 上编写图形用户界面 (GUI),应该使用 MFC(Microsoft Foundation Class) 或 Qt 等框架。你可能不知道如何在 Windows 上编写创建 GUI 的底层代码,更重要的是不想浪费时间去学习

4.2 重用代码的策略

4.2.1 理解功能和限制因素
  • 对于多线程程序而言,代码安全吗?
  • 库是否要求使用它的代码进行特定的编译器设置?如有必要,项目可以接受吗?
  • 库或框架需要什么样的初始化调用?需要什么样的清理?
  • 库或框架依赖于其他哪些库?
  • 如果从某个类继承,应该调用哪个构造函数?应该重写哪些虚方法?
  • 如果某个调用返回内存指针,调用者还是库负责内存的释放?如果库对此负责,什么时候释放内存?
  • 强烈建议查看是否可使用智能指针来管理由库分配的内存。智能指针在第 1章中讨论过。
  • 库调用检查哪些错误情况?此时做出了什么假定?如何处理错误?如何提醒客户端程序发生了错误?
  • 应该避免使用弹出消息框、将消息传递到stderr/cerr 或stdout/cout 以及终止程序的库。
  • 某个调用的全部返回值(按值或按引用)有哪些?
  • 所有可能抛出的异常有哪些?
4.2.2 大 O 表示法
  • 通常用大 O 表示法记录算法和库的性能
  • 大 O 表示法表示相对性能而不是绝对性能。例如,大 O 表示法不会指出某个算法运行需要的时间,而是指出当输入量增加时算法如何执行。大 O 表示法仅适用于速度依赖于输入的算法,不适用于没有输入或者运行时间随机的算法
  • 大 O 表示法用 O(n) 表示这个排序算法的性能。意味着使用大 O 表示法,n 表示输入量。O(n) 表示排序算法的速度是输入量的直接线性函数,并非所有算法的性能与输入量的关系都是线性的,下表按照性能好坏排序

在这里插入图片描述

4.2.3 理解性能的几点提示
  • 当数据量加倍时,算法所需要的时间也加倍,这根本就没有说需要多长时间!如果某个糟糕的算法具有较大的规模,这绝不符合需求。例如,如果算法进行了不必要的磁盘访问,可能不会影响大 O 表示法,但性能非常糟糕
  • 按照这一思路,很难比较两个具有相同大 O 运行时间的算法。例如,两个不同的排序算法都声称 O ( n l o g n ) O(nlogn) O(nlogn),如果不进行测试,很难说哪个算法实际上更快些
  • 大 O 表示法描述了算法的渐进时间复杂度,因为输入量会无限增大。对于小规模输入,大 O 时间很容易引起误解:当输入量规模不大时, O ( n 2 ) O(n^2) O(n2) 算法的实际执行性能可能要优于 O ( l o g n ) O(logn) O(logn) 算法
4.2.4 理解平台限制
  • 在开始使用库代码之前,一定要理解运行库的平台。这看上去是显而易见的,但即使是那些号称跨平台的库,在不同的平台上也会有微妙差别。此外,平台不仅包括不同的操作系统,还包括同一操作系统的不同版本
4.2.5 理解许可证和支持
  • 使用第三方的库常会带来复杂的许可证问题。为使用第三方供应商提供的库,有时必须支付许可证费用。还可能有其他的许可限制,包括出口限制。此外,开放源代码库有时会要求与其有关的任何代码都公开源代码
  • 使用第三方库还带来了支持问题。在使用某个库之前,一定要理解提交 bug 的过程,并了解修正 bug 所需的时间。如果可能,判断这个库会被支持多长时间,这样就可以相应地制定计划
4.2.6 原型
  • 当首次使用某个新库或框架时,最好编写一个快速原型。测试代码是熟悉库功能的最好方法。应该考虑在程序设计之前测试库,这样就可以熟悉库的功能和限制。这种实际检验还可判断库的性能特征
  • 即使原型应用程序与最终应用程序没有任何相似之处,花费在原型上的时间也不会浪费。不要觉得编写实际应用程序的原型很难,可编写一个虚拟程序来测试想使用的库功能,这样做是为了让自己熟悉库

5. 设计一个国际象棋程序

5.1 需求

  • 在开始设计前,应该弄清楚对于程序功能和性能的需求。理想情况下,这些需求应该是以需求规范 (requirements specification) 形式给出的文档。国际象棋程序的需求应该包含下列类型的规范,当然实际的需求规范应该比下面的内容更详细,条目更多
    • 程序支持标准的国际象棋规则
    • 程序支持两个玩家。程序不提供具有人工智能的计算机玩家
    • 程序提供基于文本的界面
      • 程序以纯文本形式提供棋盘和棋子
      • 玩家通过输入代表位置的数字在棋盘上移动棋子

5.2 设计步骤

在需要时设计应该包含图示和表格,制作图示的行业标准称为 UML(统一建模语言),UML 定义了一组标准图示,可用于说明软件设计 (如类图、序列图等)。建议使用 UML,至少也要尽量使用类似 UML 的图示。但不一定要严格遵循 UML 语法,因为图示清晰、易于理解,要比语法正确更重要

5.2.1 将程序分割为子系统
  • 设计的第一步是将程序分割为通用功能子系统,并指明子系统之间的接口和交互关系。此时不需要考虑特定的数据结构和算法,甚至不需要考虑类,只是试着感受程序不同部分和它们之间的交互关系
  • 建议使用模型-视图-控制(MVC)模式将数据存储和数据显示明确分离
    • MVC 模式建立了如下理念:许多应用程序经常要处理一组数据,处理这些数据上的一个或多个视图,并操作这些数据。在 MVC 中,这组数据称为模型,视图是模型的一个特定界面,控制器修改模型,以响应某个事件的代码。MVC 的 3 个组件在反馈循环中交互操作,动作由控制器处理,控制器会调整模型,把修改返回到视图中
    • 在 MVC 设计中,下标中的 ChessBoard 和 ChessPiece 子系统是模型部分,ChessBoardView 和ChessPieceView 是视图部分,Player 是控制器部分

在这里插入图片描述

  • 由于表格无法形象地表示子系统之间的关系,通常会使用图示来表明程序的子系统,在此箭头表示一个子系统对另一子系统的调用。下图用 UML 用例图显示了国际象棋游戏的各个子系统

在这里插入图片描述

5.2.2 选择线程模型
  • 在设计阶段,可以选择程序中高级线程的数目并指定线程的交互方式
    • 高级线程的示例有 UI 线程、音频播放线程、网络通信线程等
    • 在多线程设计中,应该尽可能避免共享数据,这样可使程序更简单、更安全
    • 如果无法避免共享数据,应该指定加锁需求。如果不熟悉或平台不支持多线程,那么程序应该是单线程
    • 然而,如果程序有多个不同的任务,每个任务都并行运行,多线程是个不错的选择。例如:图形用户界面程序经常让一个线程执行主程序,其他线程等待用户按下按钮或者选择菜单项
    • 国际象棋程序只需要一个线程来控制游戏流程
5.2.3 指定每个子系统的类层次结构
  • 国际象棋程序需要一个类层次结构来代表棋子,这个类层次结构如下图所示。在这个类层次结构中,ChessPiece 泛型类作为抽象基类,ChessPieceView 类也有类似的类层次结构

在这里插入图片描述

  • 另一个类层次结构用于 ChessBoardView 类,以实现游戏的文本界面或用户图形界面。下图给出了这个类层次结构,可以在控制台以文本方式显示棋盘,也可以用 2D 或 3D 图形显示棋盘,Player 控制器和 ChessPieceView 类层次结构的各个类也需要类似的类层次结构

在这里插入图片描述

5.2.4 指定每个子系统的类、数据结构、算法和模式

在这里插入图片描述

在这里插入图片描述

5.2.5 为每个子系统指定错误处理

在这里插入图片描述

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

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

相关文章

MMDetection环境配置与使用

在安装MMDetection时&#xff0c;耗费了近一天时间&#xff0c;其实安装很简单&#xff0c;只要保证环境对应即可&#xff08;这不是废话吗&#xff09;,总而言之&#xff0c;只要严格按照步骤Windows下环境配置就是可行的。 Window环境配置 基础环境 CUDA为10.1 创建Conda环…

AWTK实现汽车仪表Cluster/DashBoard嵌入式GUI开发(三):移植

AWTK最大优势是什么?除了免费,一个是轻量级、速度快,还有一个就是跨平台,它是为移植而生,为嵌入式而生。 而嵌入式和桌面系统最大不同在于,桌面系统的CPU是intel/AMD的X86系统,操作系统时Windows/Linux,而嵌入式则更加多样,内核可能是ARM、RISC,不同厂家基于ARM内核设…

原来,网络机架的门道也这么多

大家好&#xff0c;我的网工朋友 前几天给你们说了机房搬迁&#xff0c;发现大家对硬件设备还挺感兴趣。还没看过的看这&#xff1a;《别小瞧&#xff0c;搬迁网络机房&#xff0c;讲究的可不少》。 之前大多给你分享技术和行业经验&#xff0c;这回来点“硬的”。 如果你做的…

{} >= {} 返回 true

JavaScript 一共提供了8个比较运算符。 相等比较 相等运算符 严格相等运算符 ! 不相等运算符 ! 严格不相等运算符 非相等比较 > 大于运算符 < 小于运算符 < 小于或等于运算符 > 大于或等于运算符 这八个比较运算符分成两类&#xff1a;相等比较和非相等比较。 两…

构建vue初始化项目:vue create 命令构建vue项目

首先找到自己的文件夹 1.创建vue项目&#xff1a;vue create vue 2.选择Manually select features自定义创建 3.选择vue版本(这里选择的是vue2) 4. 5. 6. 7. 8创建完成 创建完项目后先删除node_modules然后执行 npm设置淘宝镜像加速&#xff1a;npm config set registr…

java SSM 美食资讯网系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 美食资讯网系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码 和数据库&#xff0c;系统主要采用…

chatgpt赋能python:Python如何设置画笔颜色255

Python如何设置画笔颜色255 Python是一种强大的编程语言&#xff0c;广泛应用于不同领域&#xff0c;尤其在数据分析、机器学习和人工智能方面出色。在数据可视化方面&#xff0c;Python提供了一些很好的库和函数&#xff0c;例如matplotlib和seaborn&#xff0c;这些库可以用…

使用TuyaOS幻彩灯带开发包快速开发一款智能幻彩灯带

使用TuyaOS快速开发一款智能幻彩灯带 一、亮点功能介绍二、开发包的核心优势1、丰富的基础服务和驱动2、支持Kconfig3、满足开发者自定义需求 4、支持与帮助1. 下载产品开发包2. 联系我们 如果你常看短视频&#xff0c;一定被各种炫酷的幻彩灯带产品刷屏过。随着智能幻彩灯带的…

“加密前行”-加密芯片在软件License中的应用

“ 在上篇文章中&#xff0c;我们介绍了在汽车应用中&#xff0c;软硬件加密技术在保护车辆数据和通信方面发挥着关键作用。 JokerEye&#xff0c;公众号&#xff1a;ADAS之眼 ADAS-“加密前行”:软硬件技术在汽车安全中的应用" 今天&#xff0c;我们将以实际的加密芯片案…

万物悦享推广方案范文

万物悦享推广方案范文&#xff0c;做好商城视觉优化&#xff0c;可以让你超过90%的商家#抖音商城 #抖音小店 #抖音电商 #电商干货 #干货分享 但问耕耘&#xff0c;莫问收获 优秀的人往往会寻找机遇 恭喜程总拿下成都市郫都区运营商 开启万物悦享财富 管道收益 扩展阅读&#x…

chatgpt赋能python:Python如何利用自动化输入账号密码来提高工作效率

Python如何利用自动化输入账号密码来提高工作效率 在许多日常工作中&#xff0c;我们需要频繁地登录各种各样的账号&#xff0c;并且还需要输入密码。这可能会让一些人感到繁琐和乏味&#xff0c;严重影响了工作效率和效率。幸运的是&#xff0c;Python可以帮助我们解决这个问…

考虑分布式电源的配电网无功优化问题研究(matlab代码)

目录 1 主要内容 33节点系统图 参考算例模型 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序部分参考《含分布式电源的配电网多目标优化问题研究》&#xff0c;以IEEE33节点系统为研究对象&#xff0c;采用改进单目标粒子群算法&#xff08;采用惯性权重和小生境…

国家级「超算互联网」正式部署,看看哪一类人最先吃上「红利」?

继新基建、东数西算之后&#xff0c;我国算力基础设施产业链又迎来一大利好消息——科技部发起成立国家超算互联网联合体&#xff08;以下简称“超算互联网”&#xff09;&#xff01;二级市场最先做出反应&#xff0c;算力概念股连续两日收涨&#xff0c;有个股今日涨超近10%。…

springboot项目外卖管理 day03-公共字段填充与新增删除分类

文章目录 一、公共字段自动填充1.1、问题分析1.2、代码实现1.2.1、在实体类的属性上加入TableField注解&#xff0c;指定自动填充的策略1.2.2按照框架要求编写元数据对象处理器&#xff0c;在此类中统一为公共字段赋值&#xff0c;此类需要实现MetaObjectHandler接口1.2.3 功能…

Java实习过程中的mybatis问题

问题 Mybatis的resultmap结果映射property报红&#xff0c;返回封装没有值 解决方案&#xff1a; 在实体类中加入getset方法 由于mybatis做映射的时候会先解析get、set方法&#xff0c;拿到get、set后面的名字&#xff0c;new一个空对象&#xff0c;如果在result中找到查询结…

打包jar,jdk8,,mysql8,nginx成exe可安装应用,进行一键安装windows系统上

参考原文&#xff1a;Inno Setup打包 mysqljdkjar成exe文件&#xff0c;进行一键安装_恭维不起的博客-CSDN博客 百度网盘链接包含jdk8,mysql8,nginx,jar 百度网盘链接&#xff1a;https://pan.baidu.com/s/1hKIJb9TBJGuhhZAlRURmMw?pwd7777 提取码&#xff1a;7777 battoex…

沐歌保健院线上预约按摩系统的设计与实现(论文+源码)_kaic

目 录 摘 要 第一章 绪论 1.1项目研究的背景 1.2开发意义 1.3项目研究现状及内容 1.4论文结构 第二章 开发技术介绍 2.1JSP技术 2.2Eclipse环境配置 2.3MySQL环境配置 第三章 系统分析 3.1系统可行性分析 3.1.1经济可行性 3.1.2技术可行性 3.1.3运行可行性 3.1.4操作可行…

Vivado下有限状态机的实现

文章目录 1011状态机的实现四状态下的移位操作 处理相对复杂的逻辑时就会用到有限状态机&#xff0c;设定好不同的状态&#xff0c;根据触发条件跳转到相应的状态&#xff0c;然后在不同的状态下做相应的处理。有限状态机主要用到 always 语句和 case 语句。 1011状态机的实现 …

【C#项目实战】Winform音频播放器的制作

Hello大家好,我是雷工! 本篇记录Winform音频播放器的制作过程。 一、开发运行环境 1、系统开发平台:Visual Studio 2022。 2、系统开发语言:C#。 二、功能说明及效果演示 1、该音频播放器可以通过音频列表,显示可播放的音频名称,通过列表框下的添加、删除按钮可以向列…

简单、漂亮、容易上手的开源 SAAS 多租户快速开发平台,已开源

简介 开源里面UI较好、较容易上手的、中台 、SAAS 、 多租户功能、最最少的代码实现功能的快速开发平台。 特点 链路追踪&#xff1a; 支持 skywalking、zikpin、pinpoint 等多种链路追踪&#xff08;案例采用 skywalking&#xff09; 布局优雅&#xff1a; 简洁、多套主题以…