首页 > 代码库 > 让自己习惯C++
让自己习惯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 dataconst char*p=greeting; //non-const pointer,const datachar* const p=greeting; // const pointer,non-const dataconst char* const p=greeting; //const pointer,const data
const std::vector<int>::iterator iter = vec.begin(); //iter的作用像个T* const*iter = 10; //没问题,改变iter所指之物++iter; //错误!iter是conststd::vector<int>::const_iterator cIter=vec.begin(); //cIter的作用像个const T**cIter=10; //错误!*cIter是constcIter++; //没问题,改变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 对象。
让自己习惯C++