你知道,当一个概念从一个专有名词变成一个普通名词时,说明它真正的深入人心了。比如Kleenex(面巾纸品牌,也指面巾纸),Xerox(施乐,复印机品牌,也指复印机)Q-Tips(化妆品品牌,也指化妆包),对吗?所以说,当我听说你可以在Visual C++.NET中使用“modern C++ design”时非常兴奋也就不希奇了。这里指的是——至少我这样认为——《Modern C++ Design》[1]所推行的基于模板的技术。
template <class E, class A, class T> inline T& Enforce(T& obj, A arg) { if (!obj) throw E(arg); return obj; }
template <class E, class A, class T> inline const T& Enforce(const T& obj, A arg) { if (!obj) throw E(arg); return obj; } (两个版本是必须的,分别对应const和非const对象。)你可以增加两个重载版本来表示你通常会抛出的那种意外和它所带参数。
Widget* pWidget = MakeWidget (); ENFORCE(pWidget)(“This widget is null and it shouldn’t!”); 此处当Enforcer对象被创建后,operator()被调用。该操作要么把传入信息添加到msg_成员变量中,要么假如pWidget非空即无错误出现就忽略所有。换句话说,正常执行路径与带一个检测的执行路径执行得一样快。这就是漂亮的地方——真正的工作只在发生错误的情况才做,
int n = …; Widget* pWidget = MakeWidget(n); ENFORCE(pWidget)(“Widget number “)(n)(“ is null and it shouldn’t!”); 我们不知道你感觉如何,反正我们对这个设计十分的满足。反过来说,谁会不喜欢一个简明的,富于表达力的,并且是高效的解决方案呢? 定制判定和抛出策略
[1] A. Alexandrescu. Modern C++ Design (Addison-Wesley Longman, 2001). [2] Andrei Alexandrescu and Petru Marginean. "Simplify your Exception-Safe Code" [3] 预备不足意思是让一名程序员接手先天不足的具体设计。 [4] Andrei Alexandrescu. "Assertions" [5] 这个规范看上去很好。但不知什么原因演变成旧规范。在COM世界中,S_TRUE是零,S_FALSE是1。不要忽略这个信息! [6] http://www.jaggersoft.com/pubs/CVu10_1.Html