当前位置: 首页 > news >正文

03.实现

实现

条款26:尽可能延后变量定义式的出现时间

条款27:尽量少做转型动作

条款28:避免返回handles指向对象内部成分

在C++中,handles是指一个指向对象的指针或引用,用于访问该对象的成员函数或成员变量。

而条款28所说的“返回handles指向对象内部成分”,是指返回指向该对象的私有成员或受保护成员的指针或引用。

这样做的问题在于,如果对该成员进行修改或者删除操作,可能会破坏该对象的不变量(invariant)或者类的封装性,导致程序出现不可预测的结果。

另外,如果返回的指针或引用是指向临时对象或已经被释放的对象,则会导致指针悬挂(dangling pointer)或引用无效的问题。

为了避免这种问题,建议使用对象的公有成员函数访问该对象的内部成分,而不是返回指向内部成分的指针或引用。

如果必须返回指针或引用,可以考虑使用智能指针(如std::shared_ptrstd::unique_ptr)来确保对象的生命周期,或者返回const指针或引用,防止被修改。

假设有一个类Person,其中有一个私有变量age表示年龄,如下所示:

class Person {
public:void SetAge(int age) { this->age = age; }  // 设置年龄int GetAge() const { return age; }  // 获取年龄
private:int age;
};

如果在该类中返回对age的引用或指针,就会存在返回handles指向对象内部成分的问题。例如:

const int& GetAgeRef() const { return age; }  // 返回对age的引用
const int* GetAgePtr() const { return &age; }  // 返回指向age的指针

在这种情况下,如果返回的引用或指针被用于修改或者删除age,将会破坏Person类的封装性,导致程序出现不可预测的结果。 为了解决这个问题,可以使用对象的公有成员函数访问该对象的内部成分,而不是返回指向内部成分的指针或引用。例如:

class Person {
public:void SetAge(int age) { this->age = age; }  // 设置年龄int GetAge() const { return age; }  // 获取年龄void SetAgeViaFunction(int age) { SetAge(age); }  // 通过公有成员函数设置年龄
private:int age;
};

在这个例子中,我们新增了一个公有成员函数SetAgeViaFunction,用于通过公有成员函数SetAge来设置年龄。这样,外部代码就不能直接访问age,而是必须通过SetAgeViaFunction来访问age,从而保证了Person类的封装性。

条款29:为“异常安全”而努力是值得的

“异常安全”是指程序在面对异常时,能够保持正确性、资源不泄漏、不破坏数据结构等性质。

在C++中,异常安全是非常重要的,因为C++支持异常机制,如果程序无法正确处理异常,可能会导致资源泄漏、内存泄漏、数据结构损坏等问题,从而影响程序的正确性和稳定性。

请记住:

  1. 异常安全函数(Exception-safe functions)即使发生异常也不会泄露资源或允许任何数据结构败坏。这样的函数区分为三种可能的保证:基本型、强烈型、不抛异常型。
  2. “强烈保证”往往能够以 copy-and-swap 实现出来,但“强烈保证“并非对所有函数都可实现或具备现实意义。
  3. 函数提供的”异常安全保证“通常最高只等于其所调用的各个函数的”异常安全保证“中的最弱者。

因此,为了确保程序的异常安全性,我们需要在编写代码时,考虑并努力实现异常安全。具体来说,我们需要注意以下几点:

  1. 确保不会让异常逃逸:在函数中抛出异常后,应该确保异常被正确地处理掉,而不是让它逃逸到函数外部,导致资源泄漏或数据结构损坏。为了避免异常逃逸,可以使用RAII技术,通过在对象构造函数中获取资源,在对象析构函数中释放资源,来保证资源的正确获取和释放。

  2. 考虑异常安全的级别:异常安全性有三个级别,分别是基本保证、弱异常安全和强异常安全。在编写代码时,应该根据情况选择最佳的异常安全级别。

    基本保证是指:如果函数出现异常,程序状态不会受到破坏,但是可能会发生资源泄漏。

    弱异常安全是指:如果函数出现异常,程序状态和资源都不会受到破坏,但是可能会出现不一致的状态。

    强异常安全是指:如果函数出现异常,程序状态和资源都不会受到破坏,而且程序状态和资源都会回到调用函数前的状态。

  3. 使用异常处理机制:在编写代码时,应该使用异常处理机制来处理异常。通过抛出异常并捕获异常,可以避免程序崩溃,并将异常抛出给调用者进行处理。在抛出异常时,应该提供一个清晰的异常信息,方便调用者进行处理。

条款30:透彻了解inlining的里里外外

条款30中的"inlining"是指C++中的内联函数,它是一种编译器的优化技术,可以将函数调用处直接替换为函数体,从而减少函数调用的开销,提高程序的性能。但是,内联函数也有一些限制和缺点,因此,在使用内联函数时,需要透彻了解其里里外外,以便能够正确地使用和优化内联函数。

具体来说,理解"inlining"的里里外外需要注意以下几点:

  1. 内联函数的适用范围:内联函数适用于函数体比较小、被频繁调用的函数。如果函数体比较大,内联函数可能会导致代码膨胀,从而影响程序的性能。因此,在使用内联函数时,需要根据实际情况进行选择。
  2. 内联函数的定义:内联函数通常需要在头文件中进行定义,以便编译器能够在编译时进行函数替换。在定义内联函数时,需要注意函数体不能包含循环、递归等语句,否则会导致编译器无法进行内联
  3. 内联函数的声明:内联函数的声明通常也需要在头文件中进行,以便其他文件能够调用内联函数。**在声明内联函数时,需要使用inline关键字,**以便告诉编译器该函数需要进行内联。
  4. 内联函数的优化:在使用内联函数时,需要注意优化内联函数的代码,以提高程序的性能。可以使用一些技巧,如避免多余的函数调用、避免局部变量过多、使用常量表达式等
  5. 内联函数的限制:内联函数也有一些限制,例如不能取地址、不能有静态变量等。在使用内联函数时,需要注意这些限制,以便正确地使用内联函数。

请记住:

  1. 将大多数inlining限制在小型、被频繁调用的函数身上。这可使日后的调试过程和二进制升级更容易,也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化。
  2. 不要只因为function templates 出现在头文件,就将它们声明为inline

如何理解“不要只因为function templates 出现在头文件,就将它们声明为inline”这句话?

在C++中,函数模板(function templates)是一种通用的函数定义方式,它可以用来定义多个具有相同功能但类型不同的函数。**由于函数模板通常需要在头文件中进行定义,因此很容易将它们声明为内联函数(inline)以提高程序的性能。**但是,在使用函数模板时,不要只因为它们出现在头文件中,就将它们声明为内联函数,而应该根据实际情况进行选择。 具体来说,不要将所有函数模板都声明为内联函数的原因有以下几点:

  1. 函数模板的大小不确定:由于函数模板可以用于定义多个函数,因此其大小在编译时是不确定的。如果将所有函数模板都声明为内联函数,可能会导致代码膨胀,从而影响程序的性能。
  2. 内联函数的适用范围有限:内联函数适用于函数体比较小、被频繁调用的函数。对于函数模板来说,其具体调用情况是不确定的,因此并不是所有函数模板都适合声明为内联函数。
  3. 其他优化方式:除了将函数模板声明为内联函数之外,还有其他一些优化方式,如使用编译器的优化选项、避免多余的函数调用等。在使用函数模板时,应该根据实际情况选择最合适的优化方式。

因此,不要只因为函数模板出现在头文件中,就将它们声明为内联函数。应该根据实际情况进行选择,综合考虑函数模板的大小、调用情况、优化方式等因素,以便选取最合适的优化方案。

如何理解“将大多数inlining限制在小型、被频繁调用的函数身上。这可使日后的调试过程和二进制升级更容易,也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化。”这句话?

这句话指出了在使用内联函数时应该将大多数内联函数限制在小型、被频繁调用的函数中,以便最大化程序的速度提升机会,并最小化潜在的代码膨胀问题,同时也方便了日后的调试过程和二进制升级。 具体来说,这句话的含义可以从以下几个方面进行解释:

  1. 内联函数的适用范围:内联函数适用于函数体比较小、被频繁调用的函数。将大多数内联函数限制在这样的函数中,可以最大化程序的速度提升机会,因为内联函数可以减少函数调用的开销。
  2. 调试和升级的问题:将内联函数限制在小型、被频繁调用的函数中,可以使调试过程更加容易,因为这些函数的代码比较简单,容易定位和排查问题。同时,也方便了二进制升级,因为这些函数的代码不会对其他部分的代码产生过多的影响。
  3. 代码膨胀问题:内联函数会将函数体直接嵌入到调用处,从而增加代码的长度。如果将所有函数都声明为内联函数,可能会导致代码膨胀,从而影响程序的性能。将大多数内联函数限制在小型、被频繁调用的函数中,可以最小化潜在的代码膨胀问题,并提高程序的性能。

综上所述,将大多数内联函数限制在小型、被频繁调用的函数中,可以最大化程序的速度提升机会,最小化潜在的代码膨胀问题,并方便了日后的调试过程和二进制升级。

条款31:将文件间的编译依存关系降至最低

条款31指出了在软件开发中,应该尽可能地将文件间的编译依存关系降至最低,以便实现更好的模块化和可重用性。具体来说,可以从以下几个方面来理解这个条款:

  1. 编译依存关系:文件间的编译依存关系指的是一个源文件(或头文件)在编译时所依赖的其他源文件(或头文件)。如果一个源文件依赖于另外的源文件,那么在编译时就需要将这些源文件一起编译,从而增加了编译时间和编译的复杂性。

  2. 最小化编译依存关系的好处:将文件间的编译依存关系降至最低,可以实现更好的模块化和可重用性。

    模块化指的是将软件系统分解为多个独立的模块,每个模块都具有清晰的接口和功能;

    可重用性指的是可以将一个模块在不同的系统中重复使用。

    最小化编译依存关系可以使得每个模块都具有清晰的接口和功能,从而提高了模块化和可重用性。

  3. 实现最小化编译依存关系的方法:实现最小化编译依存关系的方法有很多,比如使用前置声明(forward declaration)、将接口和实现分离、使用接口类(interface class)等。

    前置声明可以减少头文件之间的相互依赖;将接口和实现分离可以使得模块之间的依赖更加清晰;

    使用接口类可以将模块之间的依赖限制在接口上,从而提高了模块化和可重用性。

以下是对该条款的理解和一些实践建议:

  1. 减少头文件的依赖:尽量减少头文件之间的相互包含,只包含必要的头文件。这样可以降低编译依存关系,避免引入不必要的依赖关系。

  2. 使用前向声明(Forward Declaration):如果在头文件中只需要使用某个类的指针或引用而不需要知道其具体实现细节,可以使用前向声明来代替包含整个头文件。这样可以减少头文件的依赖关系。

  3. 使用接口类(Interface Class):将公共接口定义在一个独立的接口类中,然后在其他文件中使用该接口类而不是具体的实现类。这样可以降低对具体实现类的依赖,提高代码的可扩展性和可替换性。

  4. 使用编译器前置声明(Compiler Firewall):在某个实现文件中使用前向声明和指针/引用,然后在该文件的头文件中包含所需的具体实现。这样可以将依赖关系局限在该实现文件内部,减少对其他文件的影响。

  5. 使用纯虚函数(Pure Virtual Functions):如果某个类在其他文件中只需要通过指针或引用进行操作,可以将该类设计为纯虚函数的基类,然后使用基类的指针或引用来操作具体的子类。这样可以降低对具体子类的依赖,提高代码的灵活性和可扩展性。

总的来说,条款31的目标是通过降低文件间的编译依存关系,减少代码间的耦合性,从而提高代码的可维护性和可扩展性。通过合理的头文件设计、前向声明、接口类和编译器前置声明等技术手段,可以将依赖关系限制在合适的范围内,使代码更加模块化、可重用和易于维护。

相关文章:

03.实现

实现 条款26:尽可能延后变量定义式的出现时间 条款27:尽量少做转型动作 条款28:避免返回handles指向对象内部成分 在C中,handles是指一个指向对象的指针或引用,用于访问该对象的成员函数或成员变量。 而条款28所说…...

可视化大屏时代的到来:智慧城市管理的新思路

随着科技的不断发展,智能芯片作为一种新型的电子元件,被广泛应用于各个领域,其中智慧芯片可视化大屏是一种重要的应用形式。 一、智慧芯片可视化大屏的优势 智慧芯片可视化大屏是一种将智能芯片与大屏幕显示技术相结合的产品,山海…...

Hibernate的三种状态

1.瞬时状态(Transient) 通过new创建对象后,对象并没有立刻持久化,他并未对数据库中的数据有任何的关联,此时java对象的状态为瞬时状态,Session对于瞬时状态的java对象是一无所知的,当对象不再被其他对象引用时&#xf…...

React 中 useContext 的用法与性能问题详解

文章目录 一、useContext 是什么?二、useContext 使用场景三、使用步骤1.使用 createContext 创建一个 Context2.使用 Provider 提供值3.使用 useContext 访问 Context完整示例 四、Provider 的 value 类型五、如何在子组件中修改 context 的数据?六、使…...

流程图是什么,用什么软件做?

在工作流程中,经常会遇到需要图形化呈现整个流程的情况。流程图就是一种一目了然的图形化表现方式,便于人们理解、沟通和管理整个流程。 1.Visio Visio是一款微软公司的图表软件,可以用于创建各种类型的流程图、组织结构图、网络图、平面图…...

Linux 家目录和根目录

摘要: 在 Linux 操作系统中,家目录和根目录是两个非常重要的概念。它们是 Linux 文件系统中的两个关键节点,为用户和系统进程提供存储、管理和访问文件和目录的接口。本文旨在深入探讨和理解这两个目录的结构、功能和使用方式,同时…...

js前端跨屏效果

效果: 三个球 源码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>三个球</title> </h…...

配置华为云镜像加速器

登录华为云官网&#xff0c;点击控制台 在服务列表里面寻找swr服务 点击镜像中心&#xff0c;点击镜像加速器 {"registry-mirrors": [ "https://301dc05233c6419b810bdb22135af9eb.mirror.swr.myhuaweicloud.com" ]}配置镜像加速器 vim /etc/docker…...

Redis的四种模式:单机、主从、哨兵、集群

一、简单理解 单机模式&#xff1a;安装你的redis&#xff0c;启动服务即为单机模式。 主从模式&#xff1a;一个主节点搭配一个或多个从节点&#xff0c;无自动故障转移功能&#xff0c;主节点发生故障后&#xff0c;需要人工将其中一个从节点设置为主节点。 哨兵模式&…...

【开源】基于Vue.js的民宿预定管理系统

项目编号&#xff1a; S 058 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S058&#xff0c;文末获取源码。} 项目编号&#xff1a;S058&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用例设计2.2 功能设计2.2.1 租客角色…...

网络安全深入学习第九课——本机信息收集

文章目录 一、Windows基本信息收集1、查看当前权限2、查看指定用户的详细信息3、查看用户SID4、查看网卡配置5、查看服务器版本\补丁等6、查看系统架构7、查看安装的软件及版本8、查看本机服务信息9、查询进程信息和列表10、查看启动程序信息11、查看计划任务12、查看主机开机时…...

深入理解C语言指针基础概念:定义、内存地址与声明初始化

导言&#xff1a; 在C语言中&#xff0c;指针是一项强大而重要的概念&#xff0c;直接涉及内存的底层操作。理解指针的基础概念对于熟练运用C语言以及理解底层系统工作原理至关重要。本文将深入研究指针的定义、内存地址的概念以及指针的声明和初始化&#xff0c;帮助读者建立对…...

Django DRF版本号的处理

在restful规范中&#xff0c;后端的API中需要体现版本。如果项目比较大&#xff0c;需要些很多的视图类&#xff0c;在每一个类中都写一遍会比较麻烦&#xff0c;所以drf中也支持了全局配置。在每个版本处理的类中还定义了reverse方法&#xff0c;他是用来反向生成URL并携带相关…...

[工业自动化-25]:IDEC和泉RU2S-24D/RU4S-24D继电器的使用说明和接线方式

目录 一、外观 1.1 继电器整体&#xff1a; 1.2 继电器主体&#xff1a; 1.3 底座&#xff1a; 二、RU系列通用继电器介绍 2.1 总体 2.2 性能规格 2.3 锁存杆 2.4 信号定义与连线 - 2S系列 &#xff08;1&#xff09;24V输入 &#xff08;2&#xff09;第一路输出 …...

如何通过短视频提高转化率?

在当今信息爆炸的时代&#xff0c;如何让自己的品牌在众多的短视频中脱颖而出&#xff0c;吸引更多的潜在客户&#xff0c;是许多企业面临的问题。抖音和快手作为目前最受欢迎的短视频平台&#xff0c;为企业提供了无限的营销机会。在这篇文章中&#xff0c;我们将探讨如何通过…...

微软离Altman越近,离OpenAI就越远!

大数据产业创新服务媒体 ——聚焦数据 改变商业 在OpenAI这场连续剧中&#xff08;之所以说是连续剧&#xff0c;这个事情肯定没完&#xff0c;后面肯定还会出续集&#xff09;&#xff0c;让我倍感意外的是&#xff0c;Altman刚跟OpenAI分手&#xff0c;“离婚手续”都还没办…...

minio集群部署(k8s内)

一、前言 minio的部署有几种方式&#xff0c;分别是单节点单磁盘&#xff0c;单节点多磁盘&#xff0c;多节点多磁盘三种方式&#xff0c;本次部署使用多节点多磁盘的方式进行部署&#xff0c;minio集群多节点部署最低要求需要4个节点&#xff0c;集群扩容时也是要求扩容的节点…...

【C语言】函数(四):函数递归与迭代,二者有什么区别

目录 前言递归定义递归的两个必要条件接受一个整型值&#xff08;无符号&#xff09;&#xff0c;按照顺序打印它的每一位使用函数不允许创建临时变量&#xff0c;求字符串“abcd”的长度求n的阶乘求第n个斐波那契数 迭代总结递归与迭代的主要区别用法不同结构不同时间开销不同…...

[原创](免改BIOS)使用Clover升级旧电脑-(高阶玩法)让固态硬盘内置Win11 PE启动系统

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…...

React项目中发生空白但不报错的原因分析和解决?

文章目录 前言组件渲染问题状态管理问题异步操作问题代码错误但未抛出异常如果我们使用的是chorme浏览器的话&#xff0c;可以下载一个开发者工具&#xff0c;例如下图&#xff1a;代码审查使用调试工具日志和输出检查外部依赖异步操作终极大法&#xff0c;不到万不得已不可以使…...

一招教你免费将DeepSeek、Qwen、Kimi、GLM、mimo等主流ai大模型网页转换成本地api任意调用 彻底实现token自由!

一招教你免费将DeepSeek、Qwen、Kimi、GLM、mimo等主流ai大模型网页转换成本地api任意调用 彻底实现token自由! 关键词&#xff1a;Chat2API教程、DeepSeek本地调用、Qwen本地API、OpenAI兼容接口、本地AI代理、多模型统一管理 名称链接Chat2API客户端 下载https://dooo.fun/a…...

**基于Geolocation API的精准位置服务开发实战:从原理到Vue3+JavaScript

基于Geolocation API的精准位置服务开发实战&#xff1a;从原理到Vue3JavaScript落地应用 在现代Web应用中&#xff0c;用户地理位置信息已成为提升体验的核心要素之一。无论是地图导航、本地化推荐&#xff0c;还是安全验证机制&#xff0c;Geolocation API 都是前端获取用户实…...

ClamAV扫U盘太慢?教你3个高级参数和正则排除法,让Ubuntu病毒扫描效率翻倍

ClamAV扫描效率优化实战&#xff1a;3个高级参数与正则排除法深度解析 每次插入U盘后等待ClamAV慢悠悠地完成全盘扫描&#xff0c;看着进度条像蜗牛爬行一样前进&#xff0c;是不是让你抓狂&#xff1f;作为Linux系统管理员&#xff0c;我经历过太多这样的煎熬时刻。直到发现那…...

LIWC文本分析:如何用Python解锁语言背后的心理密码?

LIWC文本分析&#xff1a;如何用Python解锁语言背后的心理密码&#xff1f; 【免费下载链接】liwc-python Linguistic Inquiry and Word Count (LIWC) analyzer 项目地址: https://gitcode.com/gh_mirrors/li/liwc-python 你是否好奇&#xff0c;一段简单的文字背后隐藏…...

告别纸上谈兵:基于 AI Agent 架构,侠客工坊如何将移动端设备重塑为 24 小时运转的“数字员工”?

引言&#xff1a;从“对话式 AI”到“执行型 Agent”的跨越过去一年&#xff0c;大语言模型&#xff08;LLM&#xff09;的发展令人瞩目。但对于企业和开发者而言&#xff0c;单纯的“对话”已经无法满足日益增长的降本增效需求。行业正在经历一场从“Chat&#xff08;聊天&…...

虾皮 大数据开发工程师面试题精选:10道高频考题+答案解析(附PDF)

虾皮简介 虾皮(Shopee)是东南亚领航电商平台,覆盖新加坡、马来西亚、菲律宾、泰国、越南、巴西等十余个市场。作为Sea集团旗下核心业务,虾皮在深圳、北京、上海等地设有研发中心,技术栈以Java、Go、Python为主,大数据平台基于Hadoop、Spark、Flink等开源技术构建。虾皮大…...

2026年主流热门AI会议纪要工具大横评,算完效率成本账,差距竟然这么大

作为常年泡在各种会议、调研里的内容创作者&#xff0c;这段时间我横评了5款2026年主流的AI会议纪要工具&#xff0c;算完时间和成本账直接傻了——听脑AI是目前同类工具中最值得用的&#xff0c;没有之一。 直达链接&#xff1a;https://itingnao.com/home/?source3707 谁懂…...

ALLWEONE Plate编辑器集成教程:打造专业文本编辑体验

ALLWEONE Plate编辑器集成教程&#xff1a;打造专业文本编辑体验 【免费下载链接】presentation-ai ALLWEONE Open source AI presentation generator Gamma Alternative. Create professional slides with customizable themes and AI-generated content in minutes. 项目地…...

2026年转行AI产品经理,0基础小白必看!高薪风口,你准备好了吗?

2026年对于转行AI产品经理来说&#xff0c;确实是一个很好的机会。随着AI技术的快速发展和广泛应用&#xff0c;AI产品经理的需求也在不断增加&#x1f4c8;。. 从智能语音助手到自动驾驶汽车&#xff0c;从智能家居到金融风控。人工智能已经渗透到各个行业和领域。这意味着&am…...

npm恶意软件包瞄准开发者,或致组织沦陷,专家给出防范建议

npm恶意软件包威胁开发者应用开发者收到警告&#xff0c;npm JavaScript注册表中出现了恶意版本的pgserve&#xff08;一款用于应用开发的嵌入式PostgreSQL服务器&#xff09;和automagik&#xff08;一款AI编码工具&#xff09;&#xff0c;这些恶意软件包可能会感染开发者的计…...