C++箴言:使接口易于正确使用难错误使用

C++箴言:使接口易于正确使用难错误使用,第1张

C++箴言:使接口易于正确使用难错误使用,第2张

C++淹没在接口中。接口,类接口,模板接口。每一个接口都意味着客户的代码和你的代码相互影响。假设你在和通情达理的人打交道,那些客户也想把工作做好。他们想正确使用你的界面。在这种情况下,如果他们犯了一个错误,你的界面至少是部分不完善的。理想情况下,如果尝试使用的接口不符合客户的期望,代码就不会编译。相反,如果代码可以编译,那么它所做的就是客户想要的。

开发易于正确使用,但难以错误使用的界面,需要您考虑客户可能会犯的各种错误。例如,假设您正在设计一个表示时间的类的构造函数:

class Date {
public:
Date(int month,int day,int year);
...
};

乍一看,这个界面似乎是合理的(至少在美国),但客户很容易犯两种错误。首先,它们可能会以错误的顺序传递参数:

日期d(1995年3月30日);//哎呀!应该是“3,30”,而不是“30,3”

第二,他们可能会传递一个代表月或日的非法数字:

日期d(1995年2月20日);//哎呀!应该是“3,30”,而不是“2,20”

(后一个例子好像没什么,但是想想键盘,2在3旁边。这种“差一个”的错误并不少见。)

许多客户错误可以通过引入新类型来避免。事实上,类型系统是防止不适当代码被编译的主要支持者。在目前的情况下,我们可以引入简单的包装器类型来区分日、月和年,并在数据的构造函数中使用这些类型。

结构日{结构月{结构年{
显式日(int d)显式月(int m)显式年(int y)
:val(d){ }:val(m){ }:val(y){ }

int valint valint val
};};};


上课日期{
公共:
日期(常数月& m,常数日& d,常数年& y);
...
};
日期d(1995年3月30日);//错误!错误的类型

日期d(天(30),月(3),年(1995));//错误!错误的类型

日期d(月(3),日(30),年(1995));//好的,类型是正确的

将日、月和年完全类比成封装数据比简单地使用上面的struct要好,但即使struct也足以证明明智地引入新类型可以很好地防止接口的误用。

只要放置了正确的类型,通常可以合理地限制这些类型的值。例如,月份只有12个合法值,因此月份类型应该反映这一点。一种方法是用枚举来表示月份,但是枚举并不像我们希望的那样是类型安全的。例如,枚举可以用作整数。一个安全的解决方案是提前确定法定月份的设置:

类月{
公共:
静态月Jan() {返回月(1);} //返回所有有效
静态月份Feb() { return Month(2)的函数;} //月份值;请参见下面的
...//为什么这些是函数,而不是
静态Month Dec(){ return Month(12);} //对象

...//其他成员函数

private:
显式月份(int m);//防止创建新的
//月份值

...//分月数据
};
Date d(月::月(),日(30),年(1995));

如果使用函数而不是对象来表示月份的想法让您感到惊讶,可能是因为您忘记了非本地静态对象初始化的可靠性是值得怀疑的。第四项能唤起你的记忆。

另一种防止可能的客户错误的方法是限制一个类型可以做什么。施加限制的一种常见方式是添加const。例如,第3项解释了如何通过限定operator* const的返回类型来防止客户在使用用户定义的类型时犯这样的错误:

如果(a * b = c)...//哎呀,本意是做个比较!

事实上,这只是另一个让类型易于正确使用但难以错误使用的通用策略的体现:除非你有一个好的理由,否则让你的类型的行为与内置类型一致。客户已经知道像int这样的类型是如何表现的,所以你应该尽量让你的类型在任何时候都表现得同样合理。比如A和B都是int,给A * B赋值是非法的,所以除非有非常充分的理由离开这个性能,否则你的类型这么做应该是非法的。

避免与内置类型不合理不兼容的真正原因是提供具有一致行为的接口。很少有特性比一致性更容易导致易于使用的界面,也很少有特性比不一致性更容易导致令人沮丧的界面。STL容器的接口在很大程度上(尽管并不完美)是一致的,这使得它们非常容易使用。例如,每个STL容器都有一个名为size的成员函数,用来知道容器中有多少对象。与Java不同,Java对数组使用length属性,对String使用Length方法,对List使用size方法。net中,array有一个名为length的属性,而ArrayList有一个名为Count的属性。一些开发者认为集成开发环境(IDEs)可以补偿这些琐碎的矛盾,但他们错了。开发者工作中的矛盾所带来的精神折磨,是任何一个IDE都无法完全消除的。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++箴言:使接口易于正确使用难错误使用

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情