C++ 被沉没于接口中。函数接口、类接口、模板接口。每一个接口都意味着客户的代码和你的代码互相影响。假设你在和通情达理的人打交道,那些客户也想做好工作。他们想要正确使用你的接口。在这种情况下,假如他们犯了一个错误,就说明你的接口至少有部分是不完善的。在理想情况下,假如一个接口的一种尝试的用法不符合客户的预期,代码将无法编译,反过来,假如代码可以编译,那么它做的就是客户想要的。
if (a * b = c) ... // oops, meant to do a comparison! 实际上,这仅仅是另一条使类型易于正确使用而难以错误使用的普遍方针的一种表现:除非你有很棒的理由,否则就让你的类型的行为与内建类型保持一致。客户已经知道像 int 这样的类型如何表现,所以你应该努力使你的类型的表现无论何时都同样合理。例如,假如 a 和 b 是 int,给 a*b 赋值是非法的。所以除非有一个非常棒理由脱离这种表现,否则,对你的类型来说这样做也应该是非法的。
std::tr1::shared_ptr<Investment> // attempt to create a null pInv(0, getRidOfInvestment); // shared_ptr with a custom deleter; // this won’t compile 唉,这不是合法的 C++。tr1::shared_ptr 的构造函数果断要求它的第一个参数应该是一个指针,而 0 不是一个指针,它是一个 int。当然,它能转型为一个指针,但那在当前情况下并不够好用,tr1::shared_ptr 果断要求一个真正的指针。用强制转型解决这个问题:
std::tr1::shared_ptr<Investment> // create a null shared_ptr with pInv(static_cast<Investment*>(0), // getRidOfInvestment as its getRidOfInvestment); // deleter; see Item 27 for info on // static_cast 据此,实现返回一个以 getRidOfInvestment 作为 deleter 的 tr1::shared_ptr 的 createInvestment 的代码看起来就像这个样子: