您的位置:首页 > 编程语言 > C语言/C++

Effective C++ 读书笔记一

2018-03-30 00:48 441 查看
2018.3.27

几点说明

从C转向C++

内存管理

2018.3.28

哎,竟然看的第二版,也是醉了,重新看!!

正文之前

让自己习惯C++
Item 1: View C++ as a federation of languages.

Item 2: Prefer consts, enums, and inlines to #defines.

Item 3: Use const whenever possible.

Item 4: Make sure that objects are initialized before they’re used.

2018.3.39

定制new和delete
Item 49: Understand the behavior of the new-handler.

Item 50: Understand when it makes sense to replace new and delete.

Item 51: Adhere to convention when writing new and delete.

Item 52: Write placement delete if you write placement new.

小结

2018.3.27

几点说明

如今已经是2018年,所以书中凡是因为编译器而采取的折中策略,或其他实践编译就能立马知道如何修正的问题忽略。

希望快速的读完,同时期要读的书太多,而且语言只是最基本技能。

从C转向C++

条款 1:尽量用 const 和 inline 而不用#define

预处理器有很多有意思的实现,这一条款强调的是常量和短函数的用法

条款 2:尽量用iostream而不用stdio.h

感觉最大的好处是C++可以操作符重载,使用上后者更方便(习惯)

条款 3:尽量用 new 和 delete 而不用 malloc 和 free

前者自动调用构造、析构函数(常识?)其实,最重要的是要配对使用

条款 4:尽量使用 C++风格的注释

这条凑数的吧…

内存管理

条款 5:对应的 new 和 delete 要采用相同的形式

否则不可预测(这总算常识了吧…)

条款 6:析构函数里对指针成员调用 delete

析构函数做必要的内存释放(用智能指针吧!)

条款 7:预先准备好内存不够的情况

这算是内存管理的一种方式,偏基础层,以前不知道…

没有安装 new_handler,operator new 分配内存不成功时就会抛出一个标准的 std::bad_alloc 类型的异常。

typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();


当operator new无法满足内存分配需求时,它会不断调用new_handler函数(通过set_new_handler设置),直到找到足够的内存。

2018.3.28

条款 8. 写 operator new 和 operator delete 时要遵循常规

1、内存分配程序支持 new_handler 函 数并正确地处理了零内存请求,就差不

2、内存释放程序处理了空指针(既然C++保证删除空指针永远是安全的,那为啥要做?(更:因为你也得保证啊!!))

3、写 operator new[]时,要记住你面对的是“原始”内存,不能对数组里还不存在的对象进行任何操作。

PS: C++标准规定所以独立的(freestanding)类的大小都是非零值

下面的类A就是所谓的非独立类

class A
{
int a[]; //这有点像C语言里的情况,不算做大小
};


条款 9. 避免隐藏标准形式的 new

这个编译就能知道错了,原因要到条款50看

条款 10. 如果写了 operator new 就要同时写 operator delete(内存池)

这个条款下干货挺多,绝不止标题那么简单。既讲了为什么要自定义内存管理,也讲了内存池的实现方式

PS:测试发现

::operator new()和::operator delete()类似C语言的malloc和free。

自己重写的时候只关注内存分配就行了,实际调用时,构造和析构会自动调,这是编译器的功劳吧?

哎,竟然看的第二版,也是醉了,重新看!!

正文之前

1、习惯命名:

构造函数 ctor 析构函数 dtor 成员函数 mf

举例类常常写成Widget(小器具)

指向T的指针 pt Widget的引用 rw

二元操作符的左参数lhs 右参数rhs

2、书里会考虑多线程的适用性

3、三大库 STL TR1 BOOST

(我懒得打字了,条款用英文吧。。。)

让自己习惯C++

Item 1: View C++ as a federation of languages.

C++是大杂烩,C、面向对象、泛型编程、STL


Item 2: Prefer consts, enums, and inlines to #defines.

与第二版条款一相比强调了enums,其实内容基本一样


Like #defines, enums never result in that kind of unnecessary memory allocation. //枚举不会导致非必要的内存分配(好像没必要写出来)

Item 3: Use const whenever possible.

这一条款应该叫做const大全,我怎么感觉自己都会呢...就是不太熟。这一节顺便解释了const_cast、mutable的用途和目的。但是尽可能使用我有点不能接受,比如QT的API设计就不鼓励使用,关键得看用来干嘛了。(这节太长了)
>Compilers enforce bitwise constness  //mutable来帮忙


Item 4: Make sure that objects are initialized before they’re used.

千言万语一句话,不管它到底什么规则,全部初始化就对了


1、make sure that all constructors initialize everything in the object.

2、The rules of C++ stipulate that data members of an object are initialized before the body of a constructor is entered.

3、base classes are ini- tialized before derived classes , and within a class, data members are initialized in the order in which they are declared.(C++基础的东西,写下来权当….好像没用….)

不同编译单元内定义的non-local static对象初始化次序无明确定义(也没法搞),但可以用个函数封装返回引用变non-local static为local static。(有点像单例模式,个人认为为了线程安全可以写成单例模式)

To avoid using objects before they’re initialized, then, you need to do only three things. (三条总结)

First, manually initialize non-member objects of built-in types.

Second, use member initialization lists to initialize all parts of an object.

Finally, design around the initialization order uncertainty that afflicts non-local static objects defined in separate translation units.

2018.3.39

定制new和delete

Item 49: Understand the behavior of the new-handler.

对应第二版条款七,对 new(std::nothrow) C 多讲了点。
另外更具有现代C++思想了,例如用RAII来对资源管理,CRTP (curiously recurring template pattern) 作者称之为Do It For Me用来私人订制。


Item 50: Understand when it makes sense to replace new and delete.

对应第二版条款十,不过强调的是自己撸new和delete的原因。
当然说白了就是内存管理(列三点):
>内存签名(其实有点像redis里自己封装的一层内存分配API),提到内存对齐带来的问题,不知现在如何了。
>内存池解决多次分配小内存(书中提到boost库的Pool,有时间看看)。
>收集动态内存分配信息,这个值得考虑,特别是查找内存泄漏问题。


Item 51: Adhere to convention when writing new and delete.

对应第二版条款八,基本没变化


Item 52: Write placement delete if you write placement new.

这一节讲了new和delete的问题,或者说是他们的容易被忽略的细节,会造成内存泄漏。测试时发现如果没有写对应的,编译器连警告都没有(XCode9.2 编译器Apple LLVM9.0),感觉这应该由编译器提醒开发人员。


小结

起初看的是第二版,后来转到第三版,明显感觉难度在增大。前者偏功能性,后者偏功力(硬功夫)。好歹把对应部分看完了。

最实用的大概是条款4,内存管理好像走向了极端,有的干脆用智能指针来自动管理内存,有的却被越来越强调自制高效,而后者像是基础库,对我而言只能止步了。BOOST库的Pool有时间还是要看的!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: