Effective C++ 3nd 读书摘要(三、资源管理 ;四、设计与声明;五、实现)Item13 - 31

国产麒麟系统下Kettle安装避坑指南:解决aarch64架构不支持问题 本文详细解析了在国产麒麟系统上部署Kettle时遇到的aarch64架构不支持问题,提供了从获取适配的SWT库、修改启动脚本到生产环境调优的完整解决方案。文章重点解决了ARM架构与Java GUI工具的兼容性挑战,并分享了内存配置、字体显示及Carte服务部署等实战经验,助力用户在国产化环境中稳定运行ETL流程。 阅读详情

三、资源管理
Item13. 以对象管理资源
在构造函数中获得资源并在析构函数中释放资源。如tr1::shared_ptr

 

Item14. 在资源管理类中小心copying行为
抑制copying、施行引用计数法

 

Item15. 在资源管理类中提供对原始资源的访问
一如Item18的忠告,通常显式转换函数如get()、string::c_str()是比较受欢迎的,因为不太可能被误用。

 

Item16. 成对使用new和delete时要采取相同形式
new - delete
new [] - delete []

 

Item17. 以独立语句将newed对象置入智能指针
将processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
这样的语句同样可能出现资源泄漏。因为调用priority、执行new Widget、调用tr1::shared_ptr构造函数,这三者的调用次序是无法确定的(Java与C#则不这样)。

 

所以如果它以这种顺序调用:
执行new Widget、调用priority、调用tr1::shared_ptr构造函数,则万一对priority的调用导致异常,则引发资源泄漏。
所以:
std::tr1::shared_ptr<Widget> pw(new Widget);  // store newed object
                                              // in a smart pointer in a standalone statement
processWidget(pw, priority());           // this call won't leak

 

四、设计与声明
Item18. 让接口容易被正确使用,不易被误用
首先必须考虑客户可能做出什么样的错误:
如一个Date类,接口为Date(int month, int day, int year),可能用户会这样用:
Date d(30, 3, 1995);              // Oops! Should be "3, 30" , not "30, 3"
也可能会这样用:
Date d(2, 20, 1995);              // Oops! Should be "3, 30" , not "2, 20"
但如果将接口改善为Date(const Month& m, const Day& d, const Year& y);
其中Month定义为

这样的接口便不太可能被误用。

保持接口的一致性,与内置类型的行为要兼容。
一旦怀疑,请拿ints作范本。

Item19. 设计class犹如设计type
1.新type的对象应该如何被创建和销毁
2.对象的初始化和对象的赋值应该有什么样的差别
3.新type的对象如果被passed by value,意味着什么
4.什么是新type的“合法值”
5.你的新type需要配合某个inheritance graph吗
6.你的新type需要什么样的转换
7.什么样的操作符和函数对此新type而言是合理的
8.什么样的标准函数应该驳回
9.谁该取用新type的成员
10.什么是新type的“未声明接口”
11.你的新type有多么一般化
12.你真的需要一个新type吗

 

Item20. 宁以pass-by-reference-to-const替换pass-by-value
除了效率问题还可以解决slicing问题。不过不适用于内置类型、STL迭代器和函数对象,对它们应该用pass-

by-value。

 

Item21. 必须返回对象时,别妄想返回其reference
绝不要返回pointer或reference指向local stack对象、heap-allocated对象(尽量以智能指针包裹)、可能多次出现的local static对象

 

Item22. 将成员变量声明为private
protected并不比public更具有封装性

 

Item23. 宁以non-member、not-friend替换member函数
可增加封装性、包裹弹性和机能扩充性

 

Item24. 若所有参数皆需类型转换,请为此采用non-member函数
比如Rational对象与整数进行*运算:
定义:const Rational operator*(const Rational& rhs) const;
result = oneHalf * 2;                             // fine
result = 2 * oneHalf;                             // error!

定义一个non-member函数便可解决这个问题:
const Rational operator*(const Rational& lhs,     // now a non-member
                          const Rational& rhs)     // function

 

Item25. 考虑写出一个不抛异常的swap函数

编译器会查找适当的swap,优先调用T专属的swap,若没有,则使用std::swap。
成员版的swap绝不应该抛出异常

如果你提供一个member swap,也应该提供一个non-member swap来调用前者。对于classes(not templates),请特化std::swap。

五、实现
Item26. 尽可能延后变量定义式的出现时间
只要你定义了一个变量,当程序运行到此时,便得承受构造成本。所以遵循此条款不仅可以增加程序的清晰

性,还可提高效率。

 

Item27. 尽量少做转型动作
尤其在注重效率的代码中。有许多方案可以代替转型。

 

Item28. 避免返回handles指向对象内部成分
可能导致dangling handles(包括references、指针、迭代器)。

 

Item29. 为“异常安全”而努力是值得的
当异常被抛出时,带有异常安全性的函数会:
1.不泄漏任何资源
2.不允许数据败坏

 

异常安全函数提供以下三个保证之一:(如果异常被抛出,则)
1.基本承诺:没有任何对象或数据结构会因此而败坏,所有对象都处于一种内部前后一致的状态
2.强烈保证:程序状态不改变,如果函数失败,程序会回复到“调用函数之前”的状态(往往能够以copy-and-swap实现出来)
3.nothrow保证:int doSomething() throw();  并非说doSomething绝不会抛出异常,而是说若抛出异常将是严重错误,系统将调用由set_unexpected指定的函数。

 

为此在写或改代码时,首先是“是对象管理资源”,然后挑选三个“异常安全保证”中的某一个实施于你所写的每一个函数身上。应该挑选“现实可操作”条件下的最强烈等级。

 

Item30. 透彻了解inlining的里里外外
1.如果inline函数的本体很小,将使object code增加,从而增加内存占用,并减小cache的击中率。
2.inline函数对所有的virtual函数都不起作用。构造函数和析构函数通常不应该作为inline函数。
3.inline函数无法随着程序库的升级而升级,它需要所有用户到此inlining函数的客户端程序都重新编译,而如

果是个non-inline函数,则只需要重新连接就好。

 

一个合乎逻辑的策略是:一开始不要将任何函数声明为inline,日后使用80-20原则来对那些小型的、被频繁

调用的函数进行inline。

 

Item31. 将文件间的编译依存关系降到最低
针对Person,可以将Person分割为两个classes,一个只提供接口,另一个负责实现此接口。

这种设计常被称为pimpl idiom (pointer to implemenatation)。这样的类称为handle class。(另一种便是interface class,由pure virtual class构成)

 

handle class和interface class解除了接口和实现之间的耦合关系,从而降低了文件间的编译依存性。

 

这种分离体现了编译依存性最小化的本质:现实中让头文件尽可能自我满足,万一做不到,则让它与其他文

件内的声明式(而非定义式)相依存。


具体如下:
1.如果使用object references或object pointers可以完成任务,就不要使用objects。
2.如果可能,尽量以class声明式替换class定义式。
3.为声明式和定义式提供不同的头文件。如C++标准程序库头文件的<iosfwd>(fwd=forward)中包含为

iostream各组件的声明式:


// char TYPEDEFS
typedef basic_ios<char, char_traits<char> > ios;
typedef basic_streambuf<char, char_traits<char> > streambuf;
typedef basic_istream<char, char_traits<char> > istream;
typedef basic_ostream<char, char_traits<char> > ostream;
typedef basic_iostream<char, char_traits<char> > iostream;
......
,而其对应定义则分布在若干不同的头文件内,包括<iostream>,<streambuf>...。

 

但handle class和interface class是要付出性能代价的。应该以渐进方式使用这些技术(如同上一个Item),首先使用handle class和interface class,而当它们导致性能问题时再用concrete classes替换它们。

 

程序库头文件应该以“完全且仅有声明式”的形式存在,不论是否涉及templates。

基于STM32+Qt上位机设计的智慧停车场管理系统(207) 本项目设计了一套基于STM32+Qt上位机的智慧停车场管理系统。该系统融合了先进的嵌入式技术、图像识别技术、数据库技术和移动互联网技术,通过STM32硬件端实时采集车库现场信息,包括车牌识别、车位占用状态监测等,并将数据上传至Qt上位机进行处理与展示。利用MySQL数据库存储车辆出入库记录及车位使用情况,确保数据的安全性和可追溯性;通过Android手机APP为用户提供查询、支付等功能,实现远程交互与便捷服务。 阅读详情

相关推荐

手把手移植st7701s驱动:MT6763+安卓8.0屏幕适配保姆级教程

本文详细介绍了在MT6763平台上移植ST7701S驱动的完整流程,涵盖从LK层到Kernel层的适配方案,特别针对安卓8.0系统的特殊要求。通过MIPI转RGB屏幕适配的实战教程,帮助开发者解决常见显示问题,包括无显示、色彩异常和屏幕错位等,并提供高级调试技巧如彩条测试模式和闪屏解决方案。

weixin_29186249的博客 158

Effective C++之 Item 18: 使接口易于正确使用,而难以错误使用

C++ 被淹没于接口中。函数接口、类接口、模板接口。每一个接口都意味着客户的代码和你的代码互相影响。假设你在和通情达理的人打交道,那些客户也想做好工作。他们想要正确使用你的接口。在这种情况下,如果他们犯了一个错误,就说明你的接口至少有部分是不完善的。在理想情况下,如果一个接口的一种尝试的用法不符合客户的预期,代码将无法编译,反过来,如果代码可以编译,那么它做的就是客户想要的。 开发易于正确使用...

janeqi1987的专栏 177

使用Linux安装yum报错 E: Unable to correct problems, you have held broken packages.

使用Linux安装yum报错 E: Unable to correct problems, you have held broken packages.

weixin_43205954的博客 2462

Effective C++ 3nd 读书摘要(Third Edition 55 Specific Ways to Improve Your Programs and Design)

一、让自己习惯C++ Item1. 视C++为一个语言联邦 C++由以下部分组成:C、Object-Oriented C++、Template C++、STL Item2. 尽量以const、enum、inline代替#define Item3. 尽可能使用const 1.一共有这样几种const用法:char greeting[] = "Hello";

thy专栏 1302

CATIA_DELMIA_V5R2019安装包下载及安装教程破解

CATIA_V5R2019/DELMIA_V5R2019安装包下载及安装教程破解

一只机械工装熊的博客 8390

STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发

STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发STM32H750VB使用STM32CUBEMX生成工程IAR+J-LINK调试准备工作CUBEMX生成的代码问题所在如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章U

qq_37433166的博客 5346

Effective C++ 3nd 读书摘要(七、模板与泛型编程)Item41 - 48

七、模板与泛型编程C++ template mechanism is itself Turing-complete: it can be used to compute any computable value. Item41. 了解隐式接口和编译期多态对class而言,接口是显式的,以函数签名为中心;多态是通过virtual函数发生于运行期。对template来讲,接口是隐式的,奠基于有

thy专栏 1050

三种方法教你下载大模型到本地,总有一种适合你

本文主要介绍了下载大模型到本地的三种解决方案,希望能对同学们有所帮助。 文章目录 1. 场景/问题描述 2. 方案一:使用git 3. 方案二:镜像站 4. 方案三:高速下载工具(变体及自定义代码) 4.1 aria2 4.2 自定义代码

weixin_43178406的博客 17万+

Effective C++ 3nd 读书摘要(一、让自己习惯C++ ; 二、构造,析构,赋值运算)Item1 - 12

一、让自己习惯C++Item1. 视C++为一个语言联邦C++由以下部分组成:C、Object-Oriented C++、Template C++、STL Item2. 尽量以const、enum、inline代替#define Item3. 尽可能使用const1.一共有这样几种const用法:char greeting[] = "Hello";char *p = greetin

thy专栏 916

详解AUTOSAR:AUTOSAR架构中的配置文件(拓展篇—7)

查看AUTOSAR代码包时会发现一些这样格式的文件:xxx_PBcfg.c、xxx_Lcfg.c和xxx_Cfg.h,本篇博文讲一讲这几个配置文件的作用和特点。

不脱发的程序猿 2148

GEE:本地影像上传到GEE的Assets中,并输入机器学习算法中作为特征变量

当我们在 Google Earth Engine(GEE)中应用机器学习算法时,会输入一些影像作为特征变量数据,进一步根据这些特征影像去推理未知区域的数据。但是 GEE 平台上计算特征变量的 API 函数并不是非常全面,我们希望获得更多的特征用于分类。这个时候,我们可以将本地计算的特征影像上传到 GEE 中进行后续处理。本文记录了从本地上传特征数据到 GEE 的 Assets 中的教程,用于后续在 GEE 中分类或者回归使用。本文也可作为《》一文的补充。

养乐多的博客 1730

Effective C++ 3nd 读书摘要(八、定制new和delete)Item49 - 52

八、定制new和deleteItem49. 了解new-handler的行为当然operator new抛出异常以反映内存需求出错之前,会先调用一个客户指定的错误处理函数(new-handler)。namespace std {  typedef void (*new_handler)();  new_handler set_new_handler(new_handler p) throw();}

thy专栏 890

【WRF理论】配置诊断变量 &diags

【WRF理论】配置诊断变量 &diags

WW、forever的博客 137

Effective C++ 3nd 读书摘要(六、继承与面向对象设计)Item32 - 40

六、继承与面向对象设计Item32. 确定你的public继承塑模出is-a关系(即Liskov Substitution Principle)下面是一个不严谨的public继承:class Bird {public: virtual void fly(); // birds can fly ...};class Penguin:p

thy专栏 867

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Effective C++ 3nd 读书摘要(九、杂项讨论)Item53 - 55

九、杂项讨论Item53. 不要轻忽编译器的警告比如:class B {public: virtual void f() const;};class D: public B {public: virtual void f();}; 编译器会警告:warning: D::f() hides virtual B::f()因为D中的f()没有const。 

thy专栏 794

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 254

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 349

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 394

跟我学c++中级篇—类型定义的方式

本文系统阐述了编程中类型定义的重要性及c++中的实现方式。重点对比了宏定义、typedef与modern using三种机制,指出using在可读性、灵活性和模板支持上的优势,推荐优先使用。同时提醒开发者注意别名滥用、类型歧义、错误信息冗长等问题,强调统一规范与合理设计。最终结论:在现代c++开发中,应以using为主,兼顾简洁性与可维护性,避免陷入命名混乱与编译困境。

fpcc的专栏 88

【C++——类和对象(上)】筑基篇:以封装奠定面向对象之基

本文系统梳理C++类与对象的核心知识点,涵盖类的定义、访问限定符(public/private)、类作用域、对象实例化及内存布局。重点解析封装思想、this指针机制、空类大小为1字节的原因,以及类与对象在内存中的存储差异。通过对比C语言结构体与C++类,揭示面向对象设计的优势:数据保护、接口统一、命名隔离与代码可维护性提升。内容由浅入深,适合作为学习笔记与复习参考。

2602_95684935的博客 492

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 307

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 450

#SQLite 数据库笔记一:(概念 / 终端指令 / SQL 语句 / C 编程 / 回调函数)

数据库 = 数据的仓库,假设数据是海量。能力说明存储数据持久化保存,程序退出数据还在统计数据、分组、排序数据管理增、删、改、查(CRUD)嵌入式设备上也会用数据库(单片机网关、路由器、工业 HMI 都常见),因为 sqlite 体积小、无需服务进程、单文件即可。数据库 = 库 > 表 > 记录(行) > 字段(列)sqlite3 = 开源、C 写的、单文件、免安装、最多 2T 的嵌入式关系型数据库。

lwq20051110的博客 251

1-10 PostgreSQL中多表连接全解:inner/left/right/full/cross join

本文基于 PostgreSQL 15+ 完整拆解 5 种主流连接:内连接、左连接、右连接、全连接、笛卡尔连接。结合可落地的测试数据,演示每种连接的执行逻辑、返回结果,重点剖析 NULL 值对 JOIN 匹配的核心影响,彻底解决多表连接数据丢失、匹配异常、结果错乱的问题。

zhangjw34的专栏 105

【C++ 基础入门】C++继承(下):问题、底层原理与组合

C++继承(菱形继承的问题、虚继承原理、继承与组合、构造顺序)

2601_96587588的博客 802

蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级 备考:莫队算法离线区间查询详解

备赛进行时:第十八届蓝桥杯软件赛报名已于 2026-10-08 10:00 开启、12-18 14:00 截止,省赛定在 2027-04-10(C/C++·Python 程序设计 9:00–13:00);中国电子学会 2026 年 12 月软件编程(C/C++ 一级至十级、Python 一级至六级)考级报名 9/23–12/2 16:00、统考 12-12;全国青少年信息素养大赛 2026—2027 赛季算法应用主题赛也已进入复盘练兵窗口。

IT_Scratch的博客 170
上一篇: Effective C++ 3nd 读书摘要(一、让自己习惯C++ ; 二、构造,析构,赋值运算)Item1 - 12
下一篇: Effective C++ 3nd 读书摘要(六、继承与面向对象设计)Item32 - 40
thy38
博客等级 码龄19年 184粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值