《More Effective C++》------ ( 1 )
此书作者:Scott Meyers,翻译者:侯捷......
扉页: 正确的观念 重于一切....
序,目录,导读部分略过。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
基础议题部分(Basics):
条款一:仔细区分pointers和references
(1):指针可以改变指向对象,可以为NULL,可以无初始值;
(2):引用必须赋初值,并且绑定后不可改变(即 别名);
(3):一般理解下,引用更加安全和快速。
条款二:最好使用C++转型符
(1):static_cast可以视为基本与旧式C转型类似;
(2):const_cast,移除变量的const或者volatile;
(3):dynamic_cast,用于安全向下转型或者跨系转型,把Base指针(或引用)转向Derived(或sibling base)指针(或引用),失败时返回Null指针(指针转型)或抛出异常(引用转型); (异常就是 bad_cast : public exception )
(4):reinterpret_cast, 编译器平台定义不同,进行比特级别的转型,效果很不可靠,一般用于 函数指针类型转移.
条款三:绝对不要以多态( polymorphically )方式处理数组
(1):多态继承和指针算术不可以混合使用。数组对象总是会涉及到指针的算术运算。 arr[i] = *( arr + i * sizeof ( element ) ),而多态时,计算sizeof有隐患。
条款四:非必要不要提供default Constructor
(1):声明对象数组或者new 对象数组,会调用默认构造函数; CA arr[3]; 或者 CA *pArr = new CA[3];
侧面解决方式可以: CA arr[3] = { CA( xxx ), CA( yyy ) , CA( zzz ) }; 或者 CA* arr[3]指针数组;
(2):作为virsual Base的类,可以提供一个默认构造,否则要求所有继承类必须了解虚基类的一个可用构造接口。
(3):默认构造函数,可以用带默认值的假"默认"构造函数代替。 eg.声明:CA( int i = 0 ), 注意意义上的不同。
(4):若保证默认构造可以初始化类的所有必要member字段,可以提供默认构造;否则,强调使用者必须手动构造初始对象。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
操作符( Operator )
条款五:对提供“类型转换函数"保持警觉
(1):编译器喜欢两种隐式转换:
a)只需要提供一个变量的构造函数, CA( int i ) or CA( int i, double db = 1.0 )
b)显式声明的类型转换 class CA { .... operator int() const ......................}
在编译器需要一个int的地方,它发现是一个CA,或者发现一个CA,但是不适合,而一个int适合,它会试着寻找这两种函数。
(2):当需要一些明确的类型转型符号时,可以声明显式名字的函数来代替,避免被编译器误使用。 CA::AsInt() const 取代 operator int() const
(3):explicit, 强迫显式调用,用于 (1) a)的情形
(4):隐式转换有一个规则:在同一处,只允许使用一次隐式转换,不可以两次或者递归式的调用。
eg.
template<typename T> class CArray { public: class ArraySize { public: ArraySize( int iSize ) : m_iSize( iSize ) {} int Size() const { return m_iSize; } private: int m_iSize; }; CArray( ArraySize sz ) {} };
声明: CArray<int> arr( 10 ),可以成功,但是在编译器隐式转换一个int 到 CArray,不会成功。
这里的ArraySize类,成为 Proxy class( 代理类),它每个对象只为了对应的CArray对象服务,实现一种超越外观形式(本例超越隐式类型转换)的控制, 设计模式Proxy.