让自己习惯C++

2、尽量以const,enum,inline替换#define

(1) #define在预处理阶段被处理而const在编译阶段处理,如果在编译阶段宏定义的记号名称被移走,那么编译将出错,且不便于调式。

(2) 无法利用#define创建一个class专属常量,因为#define并不重视作用域。

class CostEstimate{
private:
    static const double FudgeFactor;//static class 常量声明位于头文件内
    ......
}

const double CostEstimate::FudgeFactor = 1.35;//static classs 常量定义于实现文件内

(3) 当class编译期间需要一个常量值,如果你的编译器不允许static 整数型class常量在class内设置初值,可以使用“the enum hack”补偿法

class GamePlayer{
private:
    enum{NumTurns = 5};
    int scores[NumTurns]; 
};

(4) 对于刑事函数的宏,最好改用inline函数替换#define。

3、尽可能使用const  

(1) 关键字const多才多艺

char greeting[] = "Hello";
char* p = greeting; //non-const pointer,non-const data
const char*p=greeting; //non-const pointer,const data
char* const p=greeting; // const pointer,non-const data
const char* const p=greeting; //const pointer,const data
const std::vector<int>::iterator iter = vec.begin(); //iter的作用像个T* const
*iter = 10; //没问题,改变iter所指之物
++iter;      //错误!iter是const

std::vector<int>::const_iterator cIter=vec.begin();  //cIter的作用像个const T*
*cIter=10; //错误!*cIter是const
cIter++;    //没问题,改变cIter

(2) 成员函数

将const实施与成员函数的目的是为了确认成员函数可作用于const对象身上。  

当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。  

3、确定对象被使用前已经先被初始化 

跨编译单元初始化测序

class FileSystem{  //来自你的程序库
public:
    ......
    std::size_t numDisks() const;
    ......
};
extern FileSystem tfs; //预备给客户使用的对象


class Directory{   //由程序库客户建立
public:
    Directory(params);
    .......
};

Directory::Directory(params)
{
    ....
    std::size_t disks = tfs.numDisks(); //使用tfs
    ...
}

进一步假设,这些客户决定创建一个Directory对象吗,使用临时文件:

Directory tempDir(params);//为临时文件而做的目录

现在,初始化次序的重要性显现出来了:除非tfs在tempDir之前被初始化,否则tempDir的构造函数会用到尚未初始化的tfs。但tfs和tempDir是不同的人在不同

的时间于不同的代码文件中建立起来的,它们是定义于不同的编译单元内的non-local static 对象,如何能够确定tfs会在tempDir之前先被初始化?

使用local static 代替non-local static

class FileSystem{...}; //同前
FileSystem& tfs()   //这个函数用来替换tfs对象;它在FileSystem class中可能是个static
{
    static FileSystem fs; //定义并初始化一个local static 对象
    return fs;   //返回一个reference指向上述对象
}

class Directory{...};//同前

Directory::Directory(params)
{
    ...
    std::size_t disks = tfs().numDisk(); //原来的reference to tfs现在改为tfs()
    ...
} 

Directory& tempDir(params) //这个函数用来替换tempDir对象,它在Directory class内可能是个static
{
    static Directory td; //定义并初始化local 对象
    return td;    //返回一个reference指向上述对象
}

请记住:

(1) 为内置型对象进行手工初始化,因为C++不保证初始化它们。

(2) 构造函数最好使用成员初始化列,而不要在构造函数内使用赋值操作。初值列列出的成员变量,其排列次序应该和他们在class中的声明次序相同。

(3) 为了免除"跨编译单元之初始化次序"问题,请以local static 对象替换non-local static 对象。  

  

posted @ 2014-10-06 11:04  践行者123  阅读(138)  评论(0编辑  收藏  举报