该作品是PDF文件格式请下载 福昕PDF阅读器
学会一个程式语言,是一回事儿;学会如何以此语言设计并实作出有效的程式,又是一回事儿。C++ 尤其如此,因为它很不寻常地涵盖了罕见的威力和丰富的表现力,不但建立在一个全功能的传统语言(C)之上,更提供极为广泛的物件导向(object-oriented)性质,以及对templates 和exceptions(异常状态)的支援。
从C转向C++
对每个人来说,习惯C++需要一些时间,对于已经熟悉C的程序员来说,这个过程尤其令人苦恼。因为C是C++的子集,所有的C的技术都可以继续使用,但很多用起来又不太合适。例如,C++程序员会认为指针的指针看起来很古怪,他们会问:为什么不用指针的引用来代替呢?C是一种简单的语言。它真正提供的只有有宏、指针、结构、数组和函数。不管什么问题,C都靠宏、指针、结构、数组和函数来解决。而C++不是这样。宏、指针、结构、数组和函数当然还存在,此外还有私有和保护型成员、函数重载、缺省参数、构造和析构函数、自定义操作符、内联函数、引用、友元、模板、异常、名字空间,等等。用C++比用C具有更宽广的空间,因为设计时有更多的选择可以考虑。
在面对这么多的选择时,许多C程序员墨守成规,坚持他们的老习惯。一般来说,这也不是什么很大的罪过。但某些C的习惯有悖于C++的精神本质,他们都在下面的条款进行了阐述。
内存管理
c++中涉及到的内存的管理问题可以归结为两方面:正确地得到它和有效地使用它。好的程序员会理解这两个问题为什么要以这样的顺序列出。因为执行得再快、体积再小的程序如果它不按你所想象地那样去执行,那也一点用处都没有。“正确地得到”的意思是正确地调用内存分配和释放程序;而“有效地使用”是指写特定版本的内存分配和释放程序。这里,“正确地得到”显得更重要一些。然而说到正确性,c++其实从c继承了一个很严重的头疼病,那就是内存泄露隐患。虚拟内存是个很好的发明,但虚拟内存也是有限的,并不是每个人都可以最先抢到它。
在c中,只要用malloc分配的内存没有用free返回,就会产生内存泄露。在c++中,肇事者的名字换成了new和delete,但情况基本上是一样的。当然,因为有了析构函数的出现,情况稍有改善,因为析构函数为所有将被摧毁的对象提供了一个方便的调用delete的场所。但这同时又带来了更多的烦恼,因为new和delete是隐式地调用构造函数和析构函数的。而且,因为可以在类内和类外自定义new和delete操作符,这又带来了复杂性,增加了出错的机会。下面的条款(还有条款m8)将告诉你如何避免产生那些普遍发生的问题。