让接口容易被正确使用,不易被误用
1)许多客户端错误可以因为导入新类型而获得预防。一旦正确的类型定位,限制其值有时候是通情达理的。
考虑下面的例子表现日期:
class Date{
public:
Date(int month,int day,int year);
...
};
Date d(20,30,1997); //20月不存在的
改进:
struct Day{
explicit Day(int d):val(d){}
int val;
};
struct Month{
explicit Month(int m):val(m){}
int val;
};
struct Year{
explicit Year(int y):val(y){}
int val;
};
进一步改进:
class Month{
public:
static Month Jan(){return Month(1);}
static Month Feb(){return Month(2);}
...
static Month Dec(){return Month(12);}
private:
explicit Month(int m);
};
Date d(Month::Mar(),Day(30),Year(1998));
2)让type的行为与内置type一致
3)任何接口如何要求客户必须记得某些事,就是有着“不正确使用”的倾向,客户可能忘记那些事。
std::tr1::shared_ptr<Investment> createInvestment(){
std::tr1::shared_ptr<Investment>retVal(static_cast<Investment*>(0),
getRidOfInvestment); //getRidOfInvestment是删除器
retVal=...;
return retVal;
}
private提供封装,其他不提供封装。
封装与“当其内容改变时可能造成的代码破坏量”成反比。假如有一个public成员变量,而我们最终取消它,所有使用它的客户码都被破坏;假如有一个protected成员变量,而我们最终取消它,所有使用它的derived class都会被破坏。