Loading

Effective C++ 总结笔记(三)

三、资源管理

13.以对象管理资源

1.为了防止资源泄漏,请使用RAII对象,在构造函数里面获得资源,并在析构函数里面释放资源.

2. 引用计数型智慧指针(RCSP):持续追踪多少个指针指向该资源,无人指向他时自动删除该资源,如unique_ptr、shared_ptr和auto_ptr(现在已经没有了,可能改成weak_ptr)。

14.在资源管理类中小心copying行为

一般资源管理类复制时可以选择以下做法:

禁止复制(复制不合理)。

“引用计数法”(使用tr1::shared_ptr指定“删除器”阻止引用次数为0时的删除行为)。

复制底层资源(“深度拷贝”)。

转移底部资源的拥有权(auto_ptr)。

15.在资源管理类中提供对原始资源的访问

  1. APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的办法。
  2. 对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便。

Shared_ptr等智能指针的get成员函数可以实现显式转换(安全,受欢迎)返回原始资源指针。

16.成对使用new和delete时采取相同的形式

new和delete对应,new[ ]和delete[ ]对应

17.以独立语句将newed对象置入智能指针

如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄露。

四、设计与声明

18.让接口容易被正确使用,不易被误用

1.好的接口很容易被正确使用,不容易被误用;努力达成这些性质

2.“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容;“防治误用”的办法包括建立新类型,限制类型上的操作,束缚对象值,以及消除用户的资源管理责任

3.tr1::shared_ptr支持定制型删除器,可预防DLL问题,可被用来自动解除互斥锁等等

19.设计class犹如设计type

Class的设计就是type的设计,在定义一个新type之前,回顾本条款的问题。

20. 以pass-by-reference替换pass-by-value

1. 尽量以pass-by-reference-to-const替换pass-by-value,比较高效,并可避免切割问题

2. 对于内置类型,以及STL的迭代器和函数对象pass-by-value往往更高效

原因:缺省情况下C++by value方式传递对象至函数。除非你另外指定,否则函数都是以实际实参的副本为初值,而调用端所获得的亦是函数返回值的副本,而这些副本是由对象的拷贝构造函数产出,会带来费时操作。

21.必须返回对象时,不要返回reference

1. 绝不要返回pointer或reference指向一个local stack对象(在函数退出前被销毁)

2. 不要返回pointer或reference指向一个heap对象(用户不知道如何delete)

3. 不要返回pointer或者reference指向local static对象而有可能需要多个这样的对象(同一行不能调用多次该函数,static只有一份)

22.将成员变量声明为private

1. 将成员变量隐藏在函数接口背后,可以为所有可能的实现提供弹性,例如可使得成员变量被读写时轻松通知其他对象、可以验证class的约束条件以及函数的前提和事后状态等。

2.切记将成员变量申明为private,这可具有语法的一致性、更精确的访问控制、封装、提供class作者充分的实现弹性等优点

3.protected并不比public更有封装性

如果不是private的。一旦需要改变客户的一些功能,就会破坏太多客户码(需要修改的代码更多)。

23.宁以non-member、non-friend替换member函数

1.愈多函数可访问它,数据的封装性就愈低,故member函数封装性差

2.将所有便利函数放在多个头文件内但隶属同一个命名空间,意味客户可以轻松扩展这一组便利函数,降低了编译依存性,这正是STL的做法

24.若所有参数皆需类型转换,请为此采用non-member函数

  1. 如果你要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,啊、那么这个函数必须是个non-member。
  2. Member函数的反面是non-member函数。

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

1.提供一个public swap成员函数,让它高效置换你的两个类型的两个对象值

2.在你的classtemplate所在的命名空间内提供一个non-member swap,并令他调用上述swap函数。

3.如果你正在编写一个class,为你的class特化std::swap。并令它调用你的swap成员函数。

4.如果你调用swap,请包含using声明式,以便让std::swap在你的函数内曝光可见,然后不加namespace修饰符,赤裸裸的调用swap

 

posted @   潇洒哥lh  阅读(40)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示