读书笔记:《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…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

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

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...