让接口容易被正确使用,不易被误用
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都会被破坏。