zhouqijie

接口设计与声明





让接口容易被正确使用且不易被误用

促进接口正确使用的办法,包括接口的一致性、与内置类型的行为兼容等。
防止接口误用的办法,包括建立新类型、限制类型上的操作、束缚对象值、消除客户的资源管理责任等。
智能指针shared_ptr支持自定义删除器(deletor),这可以防范DLL问题,可被用来自动解除互斥锁等等。



设计class犹如设计type

C++就像其他OOP语言一样,当你定义一个新type,也就定义了一个新type。
class的设计就是type的设计。需要面对一些问题。

  1. 如何创建和销毁。
  2. 对象初始化和赋值有什么样的差别。
  3. 怎么值传递。
  4. 合法值。
  5. 继承图系。
  6. 类型转换。
  7. 操作符。
  8. 其他。



宁以pass-by-reference-to-const替代pass-by-value

尽量以pass-by-reference-to-const替换pass-by-value。前者通常比较高效,并可避免切割问题。
以上规则并不适用于内置类型,以及STL迭代器和函数对象。对它们而言值传递更恰当。
不是小型的类型就适合值传递,对象小不意味着其复制构造函数不昂贵。



必须返回对象时,别妄想返回其reference

不要返回local栈对象的指针。(对象离开作用域被销毁)
不要返回堆对象的指针。(有时难以处理delete问题)
如果多个这样的对象,不要返回local-static的指针。(会导致重复)



将成员变量声明为private

切记将成员变量声明为private。这可赋予客户访问数据的一致性、可细微划分访问控制、允诺约束条件获得保证,并提供class作者以充分的实现弹性。
protected并不比public更具封装性。



宁以non-member、non-frient替换member函数

宁以non-member、non-frient替换member函数。这样做可以增加封装性、包裹弹性、机能扩充性。
CRE:强制减少对private变量的访问,来提升封装性。C#的扩展方法是否是这种思路的产物?



若所有参数都需要类型转换,请为此采用non-member函数

如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个非成员函数。

//成员函数    
class Rational{
public:
    const Rational operator*(const Rational& rhs) const;
}

Rational a, result;
result = a * 2;//很好
result = 2 * a;//错误    
//不合理,乘法应该符合交换律    

//修改为非成员函数  
class Rational{...}
const  Rational operator*(const Rational& lhs, const Rational& rhs){...}    



考虑写一个不抛异常的swap函数

(《Effective C++》p106-p112)

(END)