<<Effective C++>>读书笔记(4)

xiaoxiao2021-02-27  233

七.模板与泛型编程 这个以后再补 41.了解隐式接口和编译期多态 42.了解typename的双重意义 43.学习处理模板化基类内的名称: 44.将参数无关的代码抽离templates: 45.运用成员函数模板接受所有兼容类型: 46.需要类型转化时请为模板定义非成员函数: 47.请使用traits classes表现类型信息: 48.认识tempate元编程:

八.定制new和delete

49.了解new-handler的行为 a)传统的new没有异常处理,如果内存分配失败,那么就返回null,而新的new在分配出错的时候,是会抛出异常的,为了满足一些老的程序,现在仍然有no throw new,和老版本的new一样,但在这样做并不是很好,因为如果我们new一个对象,即使分配内存没有出错,但是构造函数一系列函数还是有可能有异常的 b)new-handler简单来说就是异常处理的一个函数,我们可以通过std::set_new_handler(函数指针),来设置new的异常处理函数. c)WindowsUGI编程的时候,使用不同的画笔或字体之前,先保存原来的字体资源(默认的),然后使用自己定义的,使用之后再换回原本的.关于new-handler也可以这样,先保存起来原本的new-handler,然后使用自定义的new-handler,最后再换回原来的.这样,我们就可以给不同的类定义不同的new-handler.

50.了解new和delete的替换时机 这一条主要是讲我们为什么需要自己写一个new和delete,而不是使用C++自带的new和delete呢?原因主要有以下几点: a)用来检测使用时的错误,自己写的定制版总能增加一些额外的自己想要的功能,比如用来打印log. b)为了提高性能.C++自带的关键字new,虽然能够申请内存,但是这个new是需要照顾各种情况的,小内存,大内存,短周期,长周期都需要兼顾,所以对于单独的某种内存分配,可能并不是最好的选择.定制版的new可以加快分配速度,减少内存碎片等. c)定制版的new和delete可以收集程序内存使用的情况 d)保证数据类型对齐,有些机器比较苛刻,严格要求数据类型位对齐,否则程序就会崩溃.有的时候即使不崩溃,也会降低运行效率.所以,保证数据齐位是很好的增加保险性与效率的方法.还有簇集的概念,当一组内容都位于一块内存时,就可以减少内存调页时缺页的次数,这也是增加效率的方法. e)虽然自定义的new和delete这么好,但是涉及到的内容还是很多,尤其是各种细节,所以一般都不要自己实现自定义的new或者delete,更好的方法是使用一些开源或者商业的库

51.编写new和delet时要固守常规 定制这两个操作时需要注意的地方 a)首先,new操作符内部是一个死循环,申请内存成功时会跳出循环,如果失败的话,会调用new-handler,最后会抛出bad_alloc异常. b)new内部对于申请0字节内存采用的处理方式是改为申请1字节 c)基类如果被继承了,那么使用new的时候,申请的大小很可能不是基类的大小,而是子类的大小.这时候如果不做处理的话肯定会出问题.可以改为如果大小不等于基类,那么直接改用 ::operator new(size)即原本的new进行处理. d)delete应该进行相关检测,如果要释放的指针为NULL,那么就不进行处理. e)关于delete也应该注意释放内容大于基类原本大小时的情况.也是可以调用::operator delete(size).但是,如果基类的析构函数不是virtual的话,可能传递给delete的size大小不正确,所以需要注意析构函数需要是virtual的

52.写了placement new也要写placement delete a)简单的说,就是无论什么时候,new和delete都是配对的,而且需要严格对应.我们自己写一个new的时候,有可能加入placement,比如打印log等功能,这时候,就不能再使用原本的new了,需要找一个对应的delete与其对应. b)在我们覆写了new和delete时要注意名字的覆盖原则,我们在类中自己定义了new和delete时,原本的new和delete就会被覆盖.我们需要清楚这一点.如何还想正常使用的话,可以建立一个base class,内含所有正常形式的new和delete,如果想以自定义的形式扩充标准形式,可以使用继承机制和using 声明.

九.杂项讨论

53.不要轻易忽略编译器的警告 a)Effective C++的作者举了一个非const函数继承的时候没有覆写基类const函数的例子,这个确实非常难以发现.不过有时候我们写的代码编译器并不会提醒我们任何事,这是因为我们把编译器的警告等级调得太低了.我们应该把编译器的警告级别调高,争取在最高的警告级别下也能写出少警告的代码. b)不要过分依赖编译器的报警能力,同样的问题,有的编译器会报错,而有的编译器却不会.不同的警告级别报告的内容也不相同.所以,我们还是要提高代码的严谨性. c)当我们真正对警告完全了解的时候,才可以忽略警告,千万不能看都不看就忽略了.

54.让自己熟悉包括TR1在内的标准程序库

55.让自己熟悉boost

转载请注明原文地址: https://www.6miu.com/read-3999.html

最新回复(0)