标签:
条款01 : 视C++为一个语言联邦
C++ == C(C基本语法) + Object-Oriented C++(类,封装,继承,多态……) + Template C++(泛型编程) + STL(容器,迭代器,算法,函数对象) .
条款02 : 尽量以const,enum,inline 替换#define
1. #define 不被视为语言的一部分,其所定义的符号未被加入记号表(symbol table)内,宏内无法设置断点,无法被跟踪调试;
2. #define 定义形似函数的宏(而不是定义一个常量),即使已经为宏中的所有实参加上小括号,仍有可能会遭遇麻烦(比如参数为 ++i 运算符)。
故而:
1. 对于单纯常量,最好以const对象或enums替换#defines;
2. 对于形似函数的宏(macros), 最好改用inline函数替换#defines。
注意:
1. 无法利用#define创建一个class专属常量(当然,宏也不能够提供任何封装性),因为#defines并不重视作用域(scope).一旦宏被定义,他就在其后的编译过程中有效(除非在某处被#undef)。
2. 以定义类的专属常量为例,部分编译器不允许static成员(定义为static,确保此常量至多只有一个)在其声明式上(一般是位于头文件内)获得初值,所谓的“in-class 初值设定”也只允许对整数常量进行。如下:
class CostEstimate { private: static const double FudgeFactor; // static class 常量声明,位于头文件(.h)内 ....... enum {NumTurns = 5}; // 枚举变量,用于在类声明式中提供必要的并且需要初值设定的常量 int scores[NumTurns ]; // 使用枚举常量 }; const double CostEstimate:FudgeFactor = 1.35; // static class 常量定义,位于实现文件(.cpp)内
可以使用枚举值来补偿“in class 初值设定”,其理论基础是:‘‘一个属于枚举类型的数值可权充ints被使用"。枚举类型的行为某方面说比较像#define而不像const。例如取一个const地址是合法的,但取一个enum的地址就不合法,而取一个#define的地址通常也不合法。
条款03 : 尽可能使用const
const允许你指定一个语义约束,而编译器会强制实施这项约束。
1. const修饰指针,具体如下:
char greeting[] = "Hello"; char *p = greeting; // non-const pointer,non-const data const char *p1 = greeting; //等价于“char const * p1 = greeting;” , non-const pointer,const data char * const p2 = greeting; // const pointer,non-const data char * const const p3 = greeting; // const pointer,const data
注意:对于p1指针,其所指物为const data,但这仅限对于p1指针来说是const data,如果此时用另外一个普通指针ptr同时指向p1所指物,则可以通过ptr指针修改所指物。
2. const成员函数
将const实施于成员函数的目的,是为了确认该成员函数可作用于const对象。
bitwist constness 阵营相信,成员函数只有在不更改对象之任何成员变量(static除外)时才可以说const。但却有例外:具体的说,一个更改了“指针所指物”的成员函数虽然不能算const,但如果只有指针(而非其所指物)隶属于对象,那么却可以通过定义一个普通指针ptr,指向类中成员指针所指物,则可以通过ptr修改所指物(此为上一点所描述的情况),这就导致了反直观结果:我们定义const的本意是不修改所指物。如下:
class CTextBook { public: ... char& operator[](std::size_t position) const{return pText[position];} private: char * pText; //只有指针隶属于对象 }; const CTextBook cctb("Hello"); //声明一个常量对象 char * pc = &cctb[0]; //调用const operator[]取得一个指针,指向cctb数据 *pc = ‘J‘; // cctb现在有了“Jello”这样的内容
如果需要在const成员函数内修改某些non-static成员变量的值,则可以通过对此成员变量添加一个与const相关的摆动场:mutable(可变的)。mutable释放掉non-static成员变量的bitwise constness约束。
3. 在const和non-const成员函数中避免重复
当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。如下:
Class TextBook{ public: ..... const char& operator[](std::size_t position) const { ..... ..... return text[position]; } char& operator[](std::size_t position) { return const_cast<char&>( // 将op[]返回值的const移除(常量性移除) static_cast<const TextBook&>(*this) // 为*this加上const,使之能够调用到const op[] [position] ); } }
故而:
1. 将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
2. 编译器强制实施bitwise constness ,但你编写程序时应该使用“概念上的常量性”(conceptual constness).
3. 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
水电费
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
条款01 : 视C++为一个语言联邦
Effective C++ —— 改善程序与设计的55个具体做法(三)
标签:
原文地址:http://www.cnblogs.com/yyxt/p/4799898.html