C++学习(5)--转向effective c++

来源:互联网 发布:金蝶引出数据失败 编辑:程序博客网 时间:2024/05/29 08:24
“C是一种简单的语言。它真正提供的只有有宏、指针、结构、数组和函数。不管什么问题,C都靠宏、指针、结构、数组和函数来解决。而C++不是这样。宏、指针、结构、数组和函数当然还存在,此外还有私有和保护型成员、函数重载、缺省参数、构造和析构函数、自定义操作符、内联函数、引用、友元、模板、异常、名字空间,等等。用C++比用C具有更宽广的空间,因为设计时有更多的选择可以考虑。”
开始我的effective之旅了~
条款1 我就知道这书里肯定得大谈特谈const,因为每次看代码,都被一群出其不意的const搞郁闷。没想到第一条就是,索性现在对const还是有了些浅浅的认识:
*用const代替#define我就不多说了
#define ASPECT_RATIO 1.653
const double ASPECT_RATIO = 1.653;
*定义指针常量,要用两次const,一个对const常量,一个const指针
const char * const authorName = "Scott Meyers";
*第一类的常量,要把常量限制在类中,首相要是他成为类的成员,要保证只有一份拷贝,要把它定义成静态成员;
class GamePlayer
{
private:
 static const int NUM_TURNS = 5;
}
声明后,还要定义
const int GamePlayer::NUM_TURNS;
*用普通的inline函数实现宏的效率
让#define max(a,b) ((a)>(b)?(a):(b))去死吧
用inline int max(int a, int b) { return a > b ? a:b}
最后引述一句话:“有了const和inline,你对预处理的需要减少了,但也不能完全没有它。抛弃#include的日子还很远,#ifdef/#ifndef在控制编译的过程中还扮演重要角色。预处理还不能退休,但你一定要计划给它经常放长假。”

条款2
至于为什么用iostream取代stdio,我有一个理性加感性的认识:方便。剩下的留给底层的机制去做吧,等我看底层的时候再慢慢捉摸你们去。
“如果编译器同时支持 <iostream>和<iostream.h>,那头文件名的使用会很微妙。例如,如果使用了#include <iostream>, 得到的是置于名字空间std(见条款28)下的iostream库的元素;如果使用#include <iostream.h>,得到的是置于全局空间的同样的元素。在全局空间获取元素会导致名字冲突,而设计名字空间的初衷正是用来避免这种名字冲突的发生。”
这点很重要,解决了我长久以来的疑惑。我就说为什么自从我把iostream.h改称iostream的时候
不加using namespace std;的话就会报出n多的错,now i get it  :〉
条款3:尽量用new和delete而不用malloc和free
看到这里我就要开始骂那个操蛋的《高质量c++编程》了,怪不得越看越眼熟呢,你丫抄人家也不多改改!
看了半天我也dont know why,状态不是很好
其实这句就够了
既然malloc和free对构造函数和析构函数一无所知,把malloc/free和new/delete混起来用又象嘈杂拥挤的晚会那样难以控制,那么,你最好就什么时候都一心一意地使用new和delete吧。
条款4:
这个也没啥好说的,这句比较有趣,不知道这书的作者是谁,哈哈
值得指出的是,有些老的专门为c写的预处理程序不知道处理c++风格的注释,所以象下面这种情形时,事情就不会象预想的那样:
“#define light_speedp 3e8 // m/sec (in a vacuum)
对于不熟悉c++的预处理程序来说,行尾的注释竟然成为了宏的一部分!当然,正象条款1所说的那样,你无论如何也不会用预处理来定义常量的。”
条款5:对应的new和delete要采用相同的形式
解决这类问题的规则很简单:如果你调用new时用了[],调用delete时也要用[]。如果调用new时没有用[],那调用delete时也不要用[]。
在写一个包含指针数据成员,并且提供多个构造函数的类时,牢记这一规则尤其重要。
为了避免混乱,最好杜绝对数组类型用typedefs。这其实很容易,因为标准c++库(见条款49)包含有stirng和vector模板,使用他们将会使对数组的需求减少到几乎零。
条款6:析构函数里对指针成员调用delete
现在自己做的程序还没有大道他说的那个地步,先不深究了
条款7:预先准备好内存不够的情况

大家都知道,处理内存不够所产生的异常真可以算得上是个道德上的行为,但实际做起来又会象刀架在脖子上那样痛苦。所以,你有时会不去管它,也许一直没去管它。但你心里一定还是深深地隐藏着一种罪恶感:万一new真的产生了异常怎么办?

哈哈,这句话真实说到点子上了~
用预处理的方法解决问题可以这样
#define new(ptr, type)  /
try { (ptr) = new type; } /
catch (std::bad_alloc&) { assert(0); }
但没有考虑到new有各种各样的方式
而且有可能有人会重载new
“那么,怎么办?如果想用一个很简单的出错处理方法,可以这么做:当内存分配请求不能满足时,调用你预先指定的一个出错处理函数。这个方法基于一个常规,即当operator new不能满足请求时,会在抛出异常之前调用客户指定的一个出错处理函数——一般称为new-handler函数。”
完全看不懂,基础问题……
但是没关系,还是先往下看。