读书笔记:《More Effective C++》
More Effective C++
Basics
reference & pointer
- reference 必定有值,pointer 可以为空
- reference 声明时必须定义,必须初始化
- reference 无需测试有效性,pointer 必须测试是否为 null
- reference 可以更改指向对象的值,但是无法指向其他对象,pointer 可以指向其他对象
cast
- c 转型:(type)expr
- c++ 转型:cast(expr)
- static:just like c 转型,无类型检查
- dynamic:base-》derived,有类型检查
- reinterpret:二进制重新解释,受制于编译期平台
- const:amend costness or volatileness
polymorphically array
- 使用base array pointer处理derived array,会导致未定义行为
default constructor
- 贸然提供default constructor需要在运行时测试是否值有效
- 缺乏default constructor会带来束缚
- 无法创建对象数组,只能创建指针数组
- 可以使用 placement new 创建对象数组,显式使用析构函数的 placement delete删除
- 使用 delete 删除 placement new 创建的对象会导致未定义行为
Operators
implicit conversion
- 单参数构造函数(或其余参数有默认值)
- 隐式类型转换操作符
- 隐式类型转换导致难以发现的问题:
- 构造函数标记为 explicit
- 定义显式类型转换:asType()
- 只能进行一次隐式转换,多次类型转换不会有问题
increment/decrement & prefix/postfix
- 【++i,累加后取出】:clazz& operator++()
- 返回引用,允许++++i
- 【i++,取出后累加】:const clazz operator++(clazz)
- 额外参数区分,参数不得使用
- 返回const,不允许i++++
- 为了使得逻辑一致,用increment prefix来实现increment postfix
override &&、||、,
- 重载&&、||导致问题:
- &&、||,条件满足/不满足会提前终止
- 重载后,左右式作为函数参数都会被执行
- 重载,导致问题:
- 逗号表达式,先求解左式,再求解右式,值为右式
- 重载后,函数无法保证执行顺序
new, operator new, placement new, delete, operator delete, []
- new:无法重载,operator new + constructor + placement new
- operator new:重载分配内存的行为
- void * operator new(size_t)
- placement new:重载在指定内存上构建对象
- void * operator new(size_t, void* location)
- delete:destructor + operator delete
- placement new 分配的内存无法通过 operator delete 删除
- 显式析构 + 分配内存对应的方式删除
- new->delete
- malloc->free
- 显式析构 + 分配内存对应的方式删除
- placement new 分配的内存无法通过 operator delete 删除
Exceptions
- 程序运行出错时设置状态变量或返回错误码,无法保证异常被程序处理,程序可能会异常运行;而抛出异常如果未进行捕获,程序便会立刻终止。
delete in destructor
- 将资源分配在对象内,在析构函数中删除内存
- 析构函数必然会被调用,防止因为异常产生未删除内存
exceptions in constructor
- 构造函数异常,部分构造的对象不会自动析构
- 将所有成员变量视为RAII对象,使用shared_ptr
exceptions in destructor
- 使用uncaught_exception判断析构函数时候正有一个exception在作用中
- 正在处理异常的析构函数抛出未捕获的异常,会导致程序终止
- 不应该让析构函数抛出异常,析构函数应该是异常安全的
stack unwinding
C++异常处理,栈展开机制:
- 异常被抛出
- 当前作用域,搜索异常处理程序catch块
- 未搜索到,销毁该作用域内的局部对象
- 调用析构函数出现异常,程序终止,std::terminate
- 退出当前作用域,继续搜索上一级作用域
- 未处理异常,std::terminate,std::abort,生成核心转储文件
catch exceptions param pass
- 处理异常和函数传参的区别
- 异常永远会被复制,因为异常处理程序超出函数调用作用域
- 按值捕获,复制两次,传参一次,复制一次
- 引用捕获,复制一次
- 不发生隐式类型转换,仅能发生继承类型转换
- 异常按catch的顺序处理,没有最优类型匹配
- 子类异常应该写在基类异常的前面,否则不会被处理
- 异常永远会被复制,因为异常处理程序超出函数调用作用域
catch exceptions by reference
- catch by pointer:无法判断是否应该删除资源
- catch by value:子类异常由基类捕获会导致对象切割,仅剩下基类行为
- catch by reference:推荐使用,且仅复制一次
exception specifications
- 在定义中指定函数可能抛出的异常
- 未指定则表明可能抛出任何异常
- 指定noexcept表明不会抛出任何异常
- 抛出未定义异常会导致unexpected函数调用
- unexpected的默认行为是调用terminate
- 可以使用set_unexpected自定义处理行为
- 可以提供额外的异常定义说明,但是违反说明的异常会直接导致程序终止
exception handling cost
- 异常处理会使得程序效率下降5%~10%
Efficiency
80-20 rule
- 80%的资源被20%的代码占用,不仅需要大幅优化代码,更重要的是找到那20%的瓶颈
- 不根据经验和直觉,而是使用profiler来分析那20%代码
lazy evaluation
- 如果计算不是绝对必要,使用lazy evaluation替代eager evaluation
over-eager evaluation
- cache:缓存已计算的值
- prefetch:预先从磁盘读取可能访问的值,每次读取磁盘多于请求量的值
avoid temporary
- 临时对象≠局部对象,临时对象是没有名字的栈对象
- 函数传参,隐式类型转换
- by value:隐式转换为临时对象
- by const reference:隐式转换为临时对象
- by non-const reference:隐式转化无法被触发,因为对临时对象的修改无法反馈会引用对象,因此编译报错
- 函数返回值
- 使用+=替代+
- 返回值优化RVO
- 函数传参,隐式类型转换
return value optimize
- 直接返回构造函数,避免临时对象的生成
overload to avoid implicit type conversions
- 使用函数重载来避免没有函数重载时的隐式类型转换
supply += and +
- 操作符+=往往比+有更高的效率
- 重载操作符的时候提供+=版本
third party library
- 相同功能的第三方库,在性能方面,可能会有不同的设计,和不同的效率偏重
inherit cost
- virtual functions:
- 每个class包含一个虚函数表
- 每个对象包含一个虚函数表的指针
- virtual 函数无法 inline,因为 inline 需要在编译期复制函数调用,而 virtual 需要运行期才能确定调用函数
- multiple inheritance & virtual base classes
- 菱形继承需要virtual base class,额外的指针开销
- runtime type identification,RTTI
- typeid获取class相应的type_info,需要额外的指针指向type_info
- 可以在虚函数表中添加指向type_info的指针
Techniques
virtual constructor & non-member function
- virtual constructor
- factory function 根据参数生成不同的子类
- virtual copy constructor
- 每个子类添加虚函数clone调用拷贝构造函数
- virtual non-member function
- 每个子类添加虚函数实现具体操作
- non-member function inline化,调用相应虚函数
limit class instance count
- 关键资源有限,其对应的类示例数目也有限
- 零或一:单例模式
- n:在构造函数中添加static示例计数,使用make函数显式构造,防止隐式构造增加计数
fore constructor in/out of heap
- in heap:对象有自杀能力,delete删除内存
- out of heap:对象不会造成内存泄漏
- 重载:
- static void * operator new(size_t)
- static void operator delete(void *)
smart pointers
- 智能指针无法在子类和基类之间转换,需要借助于隐式类型转换操作符
reference count
- 多数对象共享少数的实值,实值的产生和删除成本高,使用引用计数来记录共享对象的个数,在引用计数为零时删除
proxy class
- 表示一个观念上不存在的对象
- 实现[][]重载,proxy对象为Array1D
multi virtual function
- 根据多个子类的类型判断调用的函数
- func(base*, base*)
- 虚函数+RTTI,运行时类型辨识
- 虚函数重载
- 自行实现虚函数表
- func(base*, base*)
Miscellany
相关文章:
读书笔记:《More Effective C++》
More Effective C Basics reference & pointer reference 必定有值,pointer 可以为空reference 声明时必须定义,必须初始化reference 无需测试有效性,pointer 必须测试是否为 nullreference 可以更改指向对象的值,但是无法…...
手写VUE后台管理系统6 - 支持TS声明文件.d.ts
TS 使用声明文件进行类型定义。 配置 在 tsconfig.json 文件中,找到 include 属性,添加 "src/**/*.d.ts",表示 src 目录下的所有 .d.ts 文件都会被自动加载。 添加后内容如下 "include": ["src/**/*.ts",&…...
第八天:信息打点-系统端口CDN负载均衡防火墙
信息打点-系统篇&端口扫描&CDN服务&负载均衡&WAF防火墙 一、知识点 1、获取网络信息-服务器厂商: 阿里云,腾讯云,机房内部等。 网络架构: 内外网环境。 2、获取服务信息-应用协议-内网资产: FTP…...
一款充电桩解决方案设计
一、基本的概述 项目由IP6536提供两路5V 1.5A 的USB充电口,IP6505提供一路最大24W的USB快充口支持QC3.0 / DCP / QC2.0 / MTK PE1.1 / PE2.0 / FCP / SCP / AFC / SFCP的快充协议,电池充电由type-C输入经过IP2326输出最高15W快充对电池进行充电…...
Leetcode 2953. Count Complete Substrings
Leetcode 2953. Count Complete Substrings 1. 解题思路2. 代码实现 题目链接:2953. Count Complete Substrings 1. 解题思路 这一题麻烦的点就在于说有两个限制条件,但是好的点在于说这两个限制条件事实上是相互独立的。 因此,我们可以通…...
【Python-第三方库-pywin32】随笔- Python通过`pywin32`获取窗口的属性
Python通过pywin32获取窗口的属性 基础 获取所有窗口的句柄 【代码】 import win32guidef get_all_windows():hWnd_list []win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWnd_list)print(hWnd_list)return hWnd_list【结果】 获取窗口的子窗口句柄 【代…...
Flask使用线程异步执行耗时任务
1 问题说明 1.1 任务简述 在开发Flask应用中一定会遇到执行耗时任务,但是Flask是轻量级的同步框架,即在单个请求时服务会阻被塞,直到任务完成(注意:当前请求被阻塞不会影响到其他请求)。 解决异步问题有…...
zabbix监控nginx
zabbix是什么 web界面提供的一种可视化的监控服务软件 以分布式的方式系统监控以及网络监控,硬件监控等等开源的软件 zabbix的架构 1、c/s模式 客户端和服务端,zabbix server服务端 zabbix agent 客户端 2、通过B/S B是浏览器 S服务端,通…...
【CVE-2023-49103】ownCloud graphapi信息泄露漏洞(2023年11月发布)
漏洞简介 ownCloud owncloud/graphapi 0.2.x在0.2.1之前和0.3.x在0.3.1之前存在漏洞。graphapi应用程序依赖于提供URL的第三方GetPhpInfo.php库。当访问此URL时,会显示PHP环境的配置详细信息(phpinfo)。此信息包括Web服务器的所有环境变量&a…...
可视化数据库管理客户端:Adminer
简介:Adminer(前身为phpMinAdmin)是一个用PHP编写的功能齐全的数据库管理工具。与phpMyAdmin相反,它由一个可以部署到目标服务器的文件组成。Adminer可用于MySQL、PostgreSQL、SQLite、MS SQL、Oracle、Firebird、SimpleDB、Elast…...
Python----字典练习
相关链接:Python---字典的增、删、改、查操作_python中字典的增删改查-CSDN博客 Python---字典---dict-CSDN博客 Python---引用变量与可变、非可变类型-CSDN博客 重点: 字典中的 key (就是键)可以是很多数据类型(…...
CentOS 部署 WBO 在线协作白板
1)WBO 白板工具介绍 1.1)WBO 白板简介 WBO 是一个自由和开源的在线协作白板。它允许多个用户同时在一个虚拟的大型白板上画图。该白板对所有线上用户实时更新,并且状态始终保持。它可以用于许多不同的目的,包括艺术、娱乐、设计和…...
qt-C++笔记之QStringList
qt-C笔记之QStringList —— 杭州 2023-12-03 文章目录 qt-C笔记之QStringList1.1.《Qt官方文档》第一部分翻译:继承自QList\<QString\>-初始化-添加字符串1.2.迭代字符串1.3.join()和split()1.4.filter()1.5.lastIndexOf()1.6.indexOf()1.7.replaceInString…...
ply前端
ply 是 eBPF 的 front-end 前端工具之一,专为 embedded Linux systems 开发,采用 C 语言编写,只需 libc 和内核支持 BPF 就可以运行,不需要外部 kernel 模块,不需要 LLVM,不需要 python。 ply 由瑞典工程师…...
U盘不仅能在电脑上使用,在手机上也可使用,包括安卓和苹果手机,但苹果的较特殊
许多最好的安卓手机都使用USB-C端口在电脑上充电和来回传输文件,但如果你需要给老板发电子邮件的文件放在闪存驱动器或全尺寸SD卡上呢? 幸运的是,使用廉价的适配器电缆,你可以将USB加密狗或读卡器直接连接到手机上。你甚至可以直接使用USB-C闪存驱动器,以实现更轻松的过程…...
面试数据库八股文十问十答第二期
面试数据库八股文十问十答第二期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的! ⭐点赞⭐收藏⭐不迷路!⭐ 1.MySQL的主从复制 MySQL的主从复制是什么?MySQL主从复制是一种常见的…...
【LeetCode】每日一题 2023_12_2 拼车(模拟/差分)
文章目录 刷题前唠嗑题目:拼车题目描述代码与解题思路学习大佬题解 刷题前唠嗑 LeetCode?启动!!! 题目:拼车 题目链接:1094. 拼车 题目描述 代码与解题思路 func carPooling(trips [][]int…...
网络和Linux网络_7(传输层)UDP和TCP协议(端口号+确认应答+超时重传+三次握手四次挥手)
目录 1. 重看端口号 1.1 端口号的概念 1.2 端口号的划分 2. 重看UDP协议 2.1 UDP协议格式 2.2 UDP的特点 3. 重看TCP协议 3.1 TCP协议格式 3.2 TCP的解包分用 3.3 TCP的可靠性及机制 3.3.1 确认应答ACK机制 3.3.2 超时重传机制 3.3.3 连接管理机制(三次…...
KALI LINUX安全审核
预计更新 第一章 入门 1.1 什么是Kali Linux? 1.2 安装Kali Linux 1.3 Kali Linux桌面环境介绍 1.4 基本命令和工具 第二章 信息收集 1.1 网络扫描 1.2 端口扫描 1.3 漏洞扫描 1.4 社交工程学 第三章 攻击和渗透测试 1.1 密码破解 1.2 暴力破解 1.3 漏洞利用 1.4 …...
2023-12-03-解决libxkbcommon库编译完后图像界面不能使用键盘
layout: post # 使用的布局(不需要改) title: Ubuntu修复 # 标题 subtitle: 解决libxkbcommon库编译完图形界面不能使用键盘 #副标题 date: 2023-12-03 # 时间 author: BY ThreeStones1029 # 作者 header-img: img/about_bg.jpg #这篇文章标题背景图片 c…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...
