Timothy

链接

《More Effective C++》------ ( 2 )

《More Effective C++》------ ( 1 )

Timothy posted @ 2010年6月02日 23:15 in Reading Notes , 1143 阅读

此书作者: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.