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

条例18~23(设计与声明)

目录

条例18

让接口被正确使用,不易被误用

总结

条例19

设计class犹如设计type

条例20

宁以const的引用传参替代传值传参

总结

条例21

必须返回对象时,别妄想返回他的引用

总结

条例22

将成员变量声明为private

总结

条例23

宁以非友元非成员函数替换成员函数

总结


条例18

让接口被正确使用,不易被误用

  • 我们不能总是指望客户正确的使用接口。接口本身的设计就应该阻止用户非法的使用接口。
  • 我们可以通过让参数变成指定类型,来防止类型错误的问题。给所有参数都提供一个独有的类,让客户传参的时候通过对应类型的构造函数造出对应的对象。这样当客户试图用不同类型的参数传参的时候,编译器会发现并报错。
  • 限制客户另一个错误的办法是限制类型内什么是可以做,什么是不能做。例如适当的加const.
  • 同时不能过度依赖让客户做某些事,比如delete。因为客户可能不会释放或者释放两次。可以让返回的资源直接寄托给智能指针,不给客户操作的机会。同时为了防止客户对我们返回的值进行错误的析构,我们可以直接在share_ptr内绑定上指定的删除器。由于share_ptr的构造函数固定需要传指针,有的时候我们可能没有拿到原生指针,可以先用static_cast构造出智能指针,在获得了对象后再交给智能指针管理。若能直接获得对象就可以直接交给智能指针效率会更高一些。
  • 使用share_ptr的另一个优点是会自动使用它的每个指针专属的删除器。这样就能消除交叉动态链接问题。这个问题是一个dll new 了一个对象却在另一个dll内被释放。但share智能指针的删除器会追踪会原来的dll.

总结

  • 好的接口很容易被正常使用,不容易被误用。应该在所有接口努力达成这些性质
  • 促进正确使用的办法包括接口的一致性,以及与内置行为兼容
  • 阻止误用的办法包括建立新类型,限制操作,消除客户的资源管理责任,束缚对象值
  • 使用share_ptr的定制删除器用来防范dll问题,还可以用来自动解除互斥锁。

条例19

设计class犹如设计type

  • class设计就是type的设计。在定义一个新的type之前,要考虑之前条例的所有细节

条例20

宁以const的引用传参替代传值传参

  • 通常情况下传值拷贝的效率是十分低下的,尤其在继承之后的类传值拷贝的时候,需要拷贝其父类,用引用会很大的提高效率。通过引用可以规避调用构造函数和析构函数。同时在使用引用的时候最好声明为const,否则会产生引用的对象是否会被更改的忧虑。
  • 同时使用引用传参还能避免对象切割问题。当一个子类以传值拷贝的方式传递并且被视为父类的时候,就会把它当作父类而不是子类,从而调用父类的函数,这就导致了切片问题。这个问题可以通过传引用const来解决。
  • 引用的底层往往通过指针来实现,若有个对象是内置类型,则可以考虑传值拷贝。以情况而定,若对象小其内含的东西大则复制拷贝十分昂贵。
  • 可以假设适合传值拷贝的对象是内置类型,和stl的迭代器和函数对象

总结

  • 尽量以const的引用替换传值拷贝,前者比较高效,并可避免切割问题。
  • 以上规则不适用于内置类型,以及stl的迭代器和函数对象。对这些而言使用传值拷贝更加恰当。

条例21

必须返回对象时,别妄想返回他的引用

  • 并不是所有函数的返回值都适合返回引用。因为引用是起别名,有的时候可能根没有可以引用返回的对象,这时若坚持使用引用就需要主动创建对象.有两种方式创建对象,在堆上或者在栈上。这又导致了新的问题,你需要调用构造函数和析构函数。并且有可能会导致返回一个已经被销毁的对象。若用static解决这个问题又会面临线程安全问题。

总结

  • 绝不能返回一个指向栈上对象的指针或者引用,或者返回一个指向堆上对象的引用,或者返回一个局部静态变量。
  • 该使用传值拷贝的时候不要坚持使用引用返回

条例22

将成员变量声明为private

  • 若成员变量不是public,则外来客户只能通过接口访问类内成员,这样能保持接口一致性。同时通过接口获取成员变量,可以在接口内对用户加上限制条件。
  • 同时使用接口意味这封装了一层,用户将对接口内的实现不知情,就算更改了内部实现,也不会影响客户的使用。将成员变量隐藏在函数接口的背后,可以为所有可能的实现提供弹性。
  • 封装很重要,而使用public意味着没有封装,意味着客户代码高度依赖类的底层成员们难以更改。使用protected并不会有效解决这个问题。即使使用保护的成员变量,在派生类的眼里和共有没有什么区别。保护成员的改变会导致派生类的改变。
  • 从封装的角度来看,只有两种权限,私有(封装)和其他(不封装)

总结

  • 将成员变量生命为private。这可赋予客户访问数据的一致性,并细化访问权限和约束条件,并让类有充分的的弹性。
  • 保护并不比公有更具有封装性。

条例23

宁以非友元非成员函数替换成员函数

  • 虽然面向对象建议数据应该静可能被封装,但有的时候同样的函数在类外实现的封装性可能会好于实现成类内成员函数。
  • 若你实现成类内成员函数,它还能访问类内的其他成员和函数。若你实现成类外的函数则不会增加访问的权限。要注意的两个点是,这个结论只是用于非友元,友元函数的访问大小和类内函数是一致的。另一个点是虽然他不是当前类的友元,但是不代表他不能成为另一个类的友元。
  • 比较自然的做法是可以写成类外函数并跟类放在同一命名空间内。同时这样也能分离不同的功能,放在不同的头文件内,但是用同一个命名空间。用户用哪个功能就包含哪个头文件即可,这样能减少编译的代码量。std官方库的组织形式就是这种。这种写法意味着用户可以在不破坏封装性的情况下拓展相关函数。只需要在对应的命名空间下新建一个头文件即可。这点是class做不到的,哪怕是用继承,因为子类不能访问父类内的私有成员。

总结

  • 宁可用非友元函数替换类内成员函数。这样做能增加封装性,弹性,和扩展性。

相关文章:

条例18~23(设计与声明)

目录 条例18 让接口被正确使用,不易被误用 总结 条例19 设计class犹如设计type 条例20 宁以const的引用传参替代传值传参 总结 条例21 必须返回对象时,别妄想返回他的引用 总结 条例22 将成员变量声明为private 总结 条例23 宁以非友元非…...

STM32 UART通信协议 基础知识

通用异步收发器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种串行、异步、全双工的通信协议。 在通信领域中,有两种数据通信方式:并行通信和串行通信。串口的数据传输是以串行方式进行的。串口在…...

nginx部署vue前端项目,访问报错500 Internal Server Error

前言 描述:当我配置好全部之后,通过 服务器 ip 地址访问,遇到报错信息:500 Internal Server Error。 情况说明 前提:我是通过Docker启动nginx容器,通过-v 绑定数据卷,将html文件和nginx.conf…...

@Excel注解

在 Java 开发中,Excel 注解通常用于标记实体类的字段,以指示与 Excel 文件的导入和导出相关的配置信息。 Excel 注解通常是自定义的注解,它可以包含多个属性,用于定义与 Excel 相关的配置,如字段的标题、顺序、数据格…...

解释器模式简介

概念: 解释器模式(Interpreter Pattern)是一种行为型设计模式,它用于定义语言的文法,并解析和执行给定语言中的表达式。该模式将每个表达式表示为一个类,并提供了一种方式来组合这些表达式以实现复杂的语句…...

图像识别技术在不同场景下有哪些应用?

图像识别技术在不同场景下的应用包括: 遥感图像识别:航空遥感和卫星遥感图像通常用图像识别技术进行加工以便提取有用的信息。该技术目前主要用于地形地质探查,森林、水利、海洋、农业等资源调查,灾害预测,环境污染监…...

阿里巴巴OceanBase介绍

前言 官网地址:https://www.oceanbase.com/ OceanBase是由蚂蚁集团完全自主研发的国产原生分布式数据库,始创于2010年。是全球唯一在 TPC-C 和 TPC-H 测试上都刷新了世界纪录的国产原生分布式数据库。 2010年,创始人阳振坤加入阿里巴巴&…...

leetcode 2560. 打家劫舍 IV

2560. 打家劫舍 IV 沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。 由于相邻的房屋装有相互连通的防盗系统,所以小偷 不会窃取相邻的房屋 。 小偷的 窃取能力 定义为他在窃取过程中能从单间房屋中窃取的 最大金额 。…...

正点原子lwIP学习笔记——Socket接口TCP实验

1. Socket接口TCP Client配置连接 配置步骤如下所示: sin_family设置为AF_INET表示IPv4网络协议;sin_port为设置端口号;sin_addr. s_addr设置远程IP地址;调用函数Socket创建Socket连接, 注意该函数的第二个参数SOCK_…...

【Flink】

事件驱动型应用 核心目标:数据流上的有状态计算 Apache Flink是一个框架和分布式处理引擎,用于对无界或有界数据流进行有状态计算。 运行逻辑 状态 把流处理需要的额外数据保存成一个“状态”,然后针对这条数据进行处理,并且更新状态。这就是所谓的“…...

大数据Flink(九十一):Array Expansion(数组列转行)和Table Function(自定义列转行)

文章目录 Array Expansion(数组列转行)和Table Function(自定义列转行)...

华为云云耀云服务器L实例评测|华为云云耀云服务器L实例CentOS的存储和备份策略

1 华为云云耀云服务器L实例介绍 华为云云耀云服务器L实例是华为云计算服务中的一种虚拟云服务器,它提供了强大的计算资源,可以在云端运行各种应用程序和服务。 华为云服务器提供了多种实例类型,包括通用型、计算优化型、内存优化型等&#…...

Web自动化测试 —— 如何进行Selenium页面数据及元素交互?啊哈

前言: Web自动化测试是一种常用的测试方式,通过在浏览器中模拟用户操作以及与页面元素的交互,可以有效地检验页面的功能性以及稳定性。Selenium是一款流行的Web自动化测试工具,在本篇文章中,我们将介绍如何使用Seleni…...

点云从入门到精通技术详解100篇-基于全景图的室内场景点云补全方法(续)

目录 3.3 模型训练及实验评估 3.3.1 模型训练 3.3.2实验评估 4 基于自...

Debezium系列之:采集数据库数据实现对表指定的字段进行加密,下游实现对表加密后的字段进行解密

Debezium系列之:采集数据库数据实现对表指定的字段进行加密,下游实现对表加密后的字段进行解密 一、需求背景二、创建表三、深入理解加密算法的实现原理四、实现对表的指定字段加密五、插入数据六、消费Topic七、实现对加密的字段进行解密八、查看数据库一、需求背景 实际应用…...

Win10 cmd如何试用tar命令压缩和解压文件夹

环境: Win10 专业版 Microsoft Windows [版本 10.0.19041.208] 问题描述: Win10 cmd如何试用tar命令压缩和解压文件夹 C:\Users\Administrator>tar --help tar(bsdtar): manipulate archive files First option must be a mode specifier:-c Cre…...

最新AI写作系统ChatGPT源码/支持GPT4.0+GPT联网提问/支持ai绘画Midjourney+Prompt+MJ以图生图+思维导图生成

一、AI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统?小编这里写一个详细图文教程吧&#x…...

AI绘画普及课【二】图生图

文章目录 三、图生图1、图生图原理2、图生图的三个关键步骤3、参数技术性解析4、随机种子的含义研究 三、图生图 内容概要: 1、图生图原理 2、图生图基本流程 3、随机种子作用解析 1、图生图原理 图生图可以帮你把一张图片画成另一种模样。在文生图中我们看到&…...

C语言 数据类型

变量声明 格式(变量类型变量名称) 变量类型:整数类型(int),浮点数类型(float) float类型可以存储带小数的数字。 用printf()打印变量,使用%d来处理整数值&#xff0c…...

瑞芯微RK3568:Debian系统如何安装Docker

本文基于HD-RK3568-IOT评估板演示Debian系统安装Docker,该方法适用于RK356X全系产品。 HD-RK3568-IOT评估板基于HD-RK3568-CORE 工业级核心板设计(双网口、双CAN、5路串口),接口丰富,适用于工业现场应用需求&#xff…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

C++ 基础特性深度解析

目录 引言 一、命名空间(namespace) C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用(reference)​ C 中的引用​ 与 C 语言的对比​ 四、inline(内联函数…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...