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

EffectiveC++

2015-10-01 20:49 330 查看

01尽量以cosnt、enum、inline替换#define

目的是以编译器替代预处理器的工作,宏定义会在编译器处理源码之前被预处理器替换掉,宏并不会进入到符号表内,当运用此常量获得一个编译信息的时候,错误无法被追踪,另外使用常量会产生比较小的代码量

另一个普遍的#define指令的用法是用它来实现那些看起来象函数而又不会导致函数调用的宏,这样语句有很多缺陷,可以使用内联函数来代替。

有了const和inline,你对预处理的需要减少了,但也不能完全没有它。抛弃#include的日子还很远,#ifdef/#ifndef在控制编译的过程中还扮演重要角色。预处理还不能退休,但你一定要计划给它经常放长假。

03尽量用iostream而不用stdio.h

scanf和printf不是类型安全的,而且没有扩展性另外,scanf/printf系列函数把要读写的变量和控制读写格式的信息分开来。

cin和cout通过重载使得编译器自己可以根据不同的变量类型选择操作符的不同形式

另外,在传递读和写的对象时采用的语法形式相同,所以不必象scanf那样死记一些规定,比如如果没有得到指针,必须加上地址符,而如果已经得到了指针,又要确定不要加上地址符。这些完全可以交给C++编译器去做。

tips:如果使用了#include iostream, 得到的是置于名字空间std下的iostream库的元素;如果使用#include iostream.h,得到的是置于全局空间的同样的元素。在全局空间获取元素会导致名字冲突,而设计名字空间的初衷正是用来避免这种名字冲突的发生。

04尽量用new和delete而不用malloc和free

malloc和free(及其变体)会产生问题的原因在于它们太简单:他们不知道构造函数和析构函数。malloc只申请空间,而new会构造对象。

调用free将会释放指针指向的内存,但内存里的对象不会调用析构函数,如果对象自己已经分配了内存那这些内存将会全部丢失。调用delete时,数组里的每个对象都会在内存释放前调用析构函数。

Tips:

1)把new和delete与malloc和free混在一起用也是个坏想法。对一个用new获取来的指针调用free,或者对一个用malloc获取来的指针调用delete,其后果是不可预测的。

2)其实,在c++程序里使用malloc和free没有错,只要保证用malloc得到的指针用free,或者用new得到的指针最后用delete来操作就可以了。千万别马虎地把new和free或malloc和delete混起来用,那只会自找麻烦。

05尽量使用c++风格的注释

06对应的new和delete要采用相同的形式

用new的时候会发生两件事。首先,内存被分配,然后,为被分配的内存调用一个或多个构造函数。用delete的时候,也有两件事发生:首先,为将被释放的内存调用一个或多个析构函数,然后,释放内存.

对于 delete来说会有这样一个重要的问题:内存中有多少个对象要被删除?这个问题简单来说就是:要被删除的指针指向的是单个对象呢,还是对象数组?这只有你来告诉delete。如果你在用delete时没用括号,delete就会认为指向的是单个对象,否则,它就会认为指向的是一个数组。

Tips:如果你调用new时用了[],调用delete时也要用[]。如果调用new时没有用[],那调用delete时也不要用[]。否则结果是不可预测的。

07析构函数里对指针成员调用delete

增加一个指针成员意味着几乎都要进行下面的工作:

·在每个构造函数里对指针进行初始化。对于一些构造函数,如果没有内存要分配给指针的话,指针要被初始化为0(即空指针)。

·删除现有的内存,通过赋值操作符分配给指针新的内存。

·在析构函数里删除指针。

删除空指针是安全的所以,在写构造函数,赋值操作符,或其他成员函数时,类的每个指针成员要么指向有效的内存,要么就指向空,那在你的析构函数里你就可以只用简单地delete掉他们,而不用担心他们是不是被new过。

08预先准备好内存不够的情况

不管是用“正规”(即抛出异常)形式的new还是“无抛出”形式的new,重要的是你必须为内存分配失败做好准备。最简单的方法是使用set_new_handler,因为它对两种形式都有用。

09写operator new和operator delete时要遵循常规

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: