读书笔记:《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…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
