条例26~30(实现)

条例26

尽可能延后变量定义式出现的时间

  • 尽可能的延后定义一个变量,因为只要你定义出来哪怕你没有使用,也得承受构造和析构成本。假如有异常抛出的情况,你定义类一个变量还没有使用的时候就抛出了异常。这个变量就直接调用了析构,做了无用功。应当尽可能的延后到使用前一刻为止。例如用拷贝构造代替构造+赋值。
  • 当遇到for循环的时候,可以将定义放在循体外面。因为多视情况下,n次赋值的情况要好于n次构造。若除非已知构造+析构的成本小于赋值的成本,则都应该遵守这种情况

总结

  • 尽可能延后变量定义式的出现,这样做能增加效率和可读性

条例27

尽量少做转型动作

  • 有两种旧式类型转换,和四种新式类型转换
    (T)expression    //旧式类型转换
    T(expression)const_cast<t>    //新式类型转换
    dynamic_cast<t>
    reinterpret_cast<t>
    static_cast<t>

    const_cast 用于将对象的常量性去处,dynamic_cast用于安全向下转型。(一般用于父类对象向子类转换)reinterpret_cast我叫他万能的强制类型转换,不具备可移植性,static_cast,用来强迫隐式转换,是非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast。

  • 尽量使用新式类型转换,因为更有辨识度,更具有安全性,编译器更容易发现代码的错误。

转型动作其实有可能包含代码

  • 比如int转换成float,因为双方在内存的存储方式不同,所以势必会产生代码。
  • 尤其是当父类指针指向子类对象的时候,由于偏移量的存在,所以会在运行期间来回跳转

转型有可能导致错误

  • 由于转型动作有可能会产生临时变量,若不注意就有可能对临时变量进行了操作,就会导致伤残。

dynamic_cast的使用场景

  • dynamic_cast的执行速度本身是很慢的,成本很高,使用时应注意。
  • 通常在拥有一个子类对象,却拥有一个父类指针的时候使用这个转型。
  • 我们可以通过两种方法解决这种场景,首先可以通过智能指针操作,这样就绕过了接口而使用智能指针进行操作。或者在父类内提供一个接口,将virtual函数向继承体系上方移动。

绝对避免连续的dynamic转型

  • 效率极低,当有这种场景应该用虚函数解决

总结

  • 尽量避免转型,注重效率时尤其避免dynamic转型
  • 若转型是必要的应将其隐藏在函数背后,而不用手动调用
  • 尽量使用新式的类型转型

条例28

尽量避免返回引用指向对象内部成分

  • 不能使用引用返回函数体内的局部变量,因为局部变量会被销毁,这样引用就空悬了
  • 若使用引用返回private成员,则会破坏原有的封装性。
  • 不仅仅是引用,上述两种情况在指针返回或是迭代器返回也是存在的。
  • 可以同过返回const 引用保持封装性

总结

  • 避免返回引用,指针,迭代器,指向对象内部。这样能增加封装性,避免虚调的发生

条款29

为异常安全而努力是值得的

  • 通常有异常安全问题的函数会导致,资源泄漏或者数据败坏(例如指针悬空等问题)。
  • 异常安全函数提供以下三种保证,基本承诺(异常抛出后任何事物仍然保持有效状态,但整体不可预期),强烈保证(若程序抛出异常,程序会恢复到调用 函数之前的状态),不抛出异常的保证(承诺绝不抛出异常)
  • 通常情况下应提供能提供的的最强烈的保证,但最常用的是强烈保证和基本承诺两种。
  • 可以采用资源管理类实现异常安全。或者将更改元素的操作语句放在有可能出现异常语句的后面,这样即使抛出异常也不会改变原来的值。

通过,采用拷贝复制策略(为打算操作的对象创建一个副本,然后对副本进行一切修改,修改操作成功后再拷贝回给原始的对象)。可以很好的实现强烈保证要求的复原操作

  • 通常拷贝复制策略是通过pimpl 手法(将所有隶属对象的数据从原对象放进另一个对象(副本)内,然后赋予原对象一个指针(指向副本))实现的。但这个策略无法保证强烈保证,因为假设你在这个策略内调用了别的函数,并且这个函数本身不是的异常安全性低于强烈保证,这时我们就需要写出代码恢复此函数调用之前的状态。就算该函数是强烈保证也不行,假如调用两个函数,一个正常执行一个抛出异常,就会造成部分更改的问题。
  • 综上,有的时候实现强烈保证有时候是不实际的,因为本身拷贝复制策略效率就很低。这时就只能提供基本保证。

总结

  • 异常安全函数即使发生异常也不会泄漏资源或者允许任何数据结构破坏,通常有三种类型的保证:基本型,强烈性,不抛异常性。
  • 强烈保证往往能够以拷贝复制实现,但强烈保证并非对所有函数都具备可实现意义。
  • 函数提供的保证级别是由所调用函数的最低等的异常安全级别决定的

条例30

透彻了解内联函数

  • 内联函数的执行动作像函数,同时又不用承受调用函数的开销,比宏好很多。
  • 过度使用内联会导致代码体积增大,降低指令高速缓存装置的击中率,带来效率降低。
  • 内联只是对编译器的一个建议,是否实现成内联是由编译器自身决定。对于所有虚函数都无法实现成内联。因为虚函数意味这运行时决定调用哪个函数,而内联需要在编译期间替换出函数本体。
  • 大多数内联是在编译器间行为。不是所有类模板都需要定义为内联。
  • 构造和析构往往不适合实现成内联。虽然你以为构造和析构不含代码适合内联,但实际上为了确保资源的正确构造和析构,同时维护异常安全性,编译器会在你的构造和析构函数里加上代码来实现这些功能,这就让他们不适合内联。
  • 内联函数意味着不能随着库函数的升级而升级,一旦有修改必须重新编译链接。

总结

  • 将大多数内联限制在小型和被频繁调用的函数身上,这样能使调试更加容易,让潜在的代码膨胀问题最小化,提升程序运行速度。
  • 不能因为类模板出现在头文件而将其声明为内联。

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

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

相关文章

Spring framework Day14:配置类的Lite模式和Full模式

前言 Lite模式和Full模式是指在软件或系统中的不同配置选项。一般来说&#xff0c;Lite模式是指较为简洁、轻量级的配置&#xff0c;而Full模式则是指更加完整、功能更丰富的配置。 Lite模式通常会去除一些不常用或占用资源较多的功能&#xff0c;以提高系统的运行效率和响应…

计算机算法分析与设计(9)---0-1背包和完全背包问题(含C++代码)

文章目录 一、0-1背包概述1.1 问题描述1.2 算法思想 二、0-1背包代码2.1 题目描述2.2 代码编写 三、完全背包概述四、完全背包代码4.1 题目描述4.1 代码编写4.2 代码优化 一、0-1背包概述 1.1 问题描述 1. 0-1背包问题&#xff1a;给定 n n n 种物品和一背包。物品 i i i 的…

【vue3】实现数据响应式(ref、shallowRef、trigger、reactive、shallowReactive、toRef、toRefs)

一、ref、shallowRef、trigger ref支持所有类型 可以粗略理解为 ref shallowRef triggerRef 1、通过ref获取dom元素 <p ref"_ref">这是ref获取dom元素</p>import {ref,shallowRef, triggerRef} from vueconst _ref ref()console.log(_ref.value?.i…

redis基本数据类型

一) 字符串(String) String是redis最基本的类型&#xff0c;value最大是512M&#xff0c;String类型是二进制安全的&#xff0c;可以包含任何数据&#xff0c;如jpg图片或者序列化的对象 1 使用场景 1) 缓存&#xff1a;redis作为缓存层&#xff0c;mysql做持久化层&#xff0…

AC修炼计划(AtCoder Regular Contest 166)

传送门&#xff1a;AtCoder Regular Contest 166 - AtCoder 一直修炼cf&#xff0c;觉得遇到了瓶颈了&#xff0c;所以想在atcode上寻求一些突破&#xff0c;今天本来想尝试vp AtCoder Regular Contest 166&#xff0c;但结局本不是很好&#xff0c;被卡了半天&#xff0c;止步…

力扣第538题 把二叉搜索树转换为累加树 c++

题目 538. 把二叉搜索树转换为累加树 中等 相关标签 树 深度优先搜索 二叉搜索树 二叉树 给出二叉 搜索 树的根节点&#xff0c;该树的节点值各不相同&#xff0c;请你将其转换为累加树&#xff08;Greater Sum Tree&#xff09;&#xff0c;使每个节点 node 的新值…

第56节——redux-toolkit中的createAction——了解

一、概念 createAction 是一个用于创建 Redux action creator 的函数&#xff0c;它可以让你更快地编写 Redux 相关的代码&#xff0c;并且更加易于阅读和维护。 二、简单示例 使用 createAction&#xff0c;你只需要传入一个字符串类型的 action type&#xff0c;然后它会返…

学习率设置太大或者太小会有哪些影响?

学习率是机器学习算法中的一个重要超参数&#xff0c;它控制了参数更新的步长。学习率设置得太大或太小都可能对训练过程产生负面影响。 1、学习率设置太大的影响 &#xff08;1&#xff09;不稳定的训练过程&#xff08;震荡&#xff09; 在机器学习中&#xff0c;震荡是指…

C语言 sizeof

定义 sizeof是C语言的一种单目操作符。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 使用方法 用于数据类型 sizeof(type) 数据类型必须用括号括住 用于变量 size…

Lua教程

Lua教程(简单易懂)-CSDN博客 博客相关解释&#xff1a; 5、循环 a {"a", "b"}for i, v in ipairs(a) doprint(i, v)end 代码创建了一个名为 a 的数组&#xff0c;并使用 ipairs 迭代这个数组的元素。运行结果显示了每个元素的索引&#xff08;下标&am…

ubuntu20.04 vins-fusion 运行记录

过程记录 环境&#xff1a; ubuntu20.04 opencv4.2.0(此次使用) 3.3.1(其他程序在使用) vins-fusion vision_opencv 1.下载VINS-Fusion和cv_bridge&#xff0c;并进行修改&#xff0c;方便使用opencv4.2.0和对应的cv_bridge。 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src…

C++数位动态规划算法:统计整数数目

题目 给你两个数字字符串 num1 和 num2 &#xff0c;以及两个整数 max_sum 和 min_sum 。如果一个整数 x 满足以下条件&#xff0c;我们称它是一个好整数&#xff1a; num1 < x < num2 min_sum < digit_sum(x) < max_sum. 请你返回好整数的数目。答案可能很大&…

【Linux】基本指令-入门级文件操作(二)

目录 基本指令 7 cp指令&#xff08;重要&#xff09; 8 mv指令&#xff08;重要&#xff09; 9 nano指令 10 cat指令 11 echo指令与重定向&#xff08;重要&#xff09; 12 more指令 13 less指令 基本指令 7 cp指令&#xff08;重要&#xff09; 功能&#xff1a;复…

redis如何实现缓存预热

在业务系统中&#xff0c;我们需要在程序启动的时候加载一些常用的数据到内存数据库中&#xff0c;从而减少业务数据库的压力。这就是我们常提到的缓存预热。官方一点的解释是这样的&#xff1a; 缓存预热是一种在程序启动或缓存失效之后&#xff0c;主动将热点数据加载到缓存中…

注意力屏蔽(Attention Masking)在Transformer中的作用 【gpt学习记录】

填充遮挡&#xff08;Padding Masking&#xff09;&#xff1a; 未来遮挡&#xff08;Future Masking&#xff09;&#xff1a;

09. 机器学习- 逻辑回归

文章目录 线性回归回顾逻辑回归 Hi&#xff0c;你好。我是茶桁。 上一节课&#xff0c;在结尾的时候咱们预约了这节课一开始对上一节课的内容进行一个回顾&#xff0c;并且预告了这节课内容主要是「逻辑回归」&#xff0c;那我们现在就开始吧。 线性回归回顾 在上一节课中&a…

如何处理接口调用的频率限制

背景 接口提供方有调用频率限制的场景下&#xff0c;如何合理设计接口请求? 方案 采用Redis队列&#xff0c;利用 lpush 和 rpop 命令来实现 首先&#xff0c;将订单依次lpush写入Redis队列。定时任务通过 rpop 获取队列订单进行接口调用。 额外说明&#xff1a; 若想查看…

flutter问题汇总

一直卡在building a flutter app for general distribution&#xff1b; AS Message窗口显示 依赖下载失败&#xff1a; 1、修改仓库地址的配置&#xff1a;android/build.gradle repositories {maven { url https://download.flutter.io }maven { url "https://maven.a…

ubuntu如何查看系统信息、cpu型号

查看当前操作系统内核信息 uname -a输出&#xff1a; Linux htu-H110M-S2 5.4.0-148-generic #165~18.04.1-Ubuntu SMP Thu Apr 20 01:14:06 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux 查看当前操作系统发行版信息 cat /etc/issueUbuntu 18.04.6 LTS \n \l 查看cpu型号 c…

Go语言入门心法(一)

Go语言入门心法(一) Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 一: go语言中变量认知 go语言中变量的定义: &#xff08;要想飞|先会走&#xff09;||&#xff08;翻身仗|抹遗憾 &#xff09; |&#xff08;二八定律&#xff09;(先量变)|(再质变)||&#x…