条款 18:让接口容易被正确使用,不易被误用

    Make interfaces easy to use correctly and hard to use incorrectly.

    下列接口容易被误用

    1. class Date {
    2. public:
    3. Date(int month, int day, int year);
    4. ...
    5. };

    可以将天数/月份/年份封装起来从而预防误用

    1. struct Day {
    2. explict Day(int d) : val(d) {}
    3. int val;
    4. };
    5. struct Month {
    6. explict Month(int m) : val(m) {}
    7. int val;
    8. };
    9. struct Year {
    10. explict Day(int y) : val(y) {}
    11. int val;
    12. };
    13. class Date {
    14. public:
    15. Date(const Month& m, const Day& d, const Year& y);
    16. ...
    17. };
    18. Date d(Moonth(3), Day(30), Year(1995));

    可以进一步限制对象的值,如月份是有12个有效值,Month 就应该反应这一事实

    1. class Month {
    2. public:
    3. static Month Jan() { return Month(1); }
    4. static Month Feb() { return Month(2); }
    5. ...
    6. static Month Dec() { return Month(12); }
    7. ...
    8. private:
    9. explicit Month(int m);
    10. ...
    11. };
    12. Date d(Month::Mar(), Day(30), Year(1995));

    除非有好理由,否则应该尽量让你的 types 的行为与内置 types 一致。
    如 a 和 b 都是 ints,那么对 a*b 赋值非法,所以如果没有特殊理由,你的 types 也应该有相同表现。
    STL 的接口就十分一致。

    std::shared_ptr 又一个特别好的性质,可以消除 cross-DLL problem。
    这个问题发生于对象在某个 DLL 中创建,却在另一个 DLL 中被 delete。
    std::shared_ptr 在指定删除器后,被用于其他 DLL 触发资源释放时,能够由该 std::shared_ptr 找到应该调用的那个 DLL 的 delete。

    • 好的接口容易被正确使用,不易被误用
    • “促进正确使用的办法包括接口的一致性”,以及内置类型的行为兼容
    • “阻止误用”的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任
    • std::shared_ptr 支持定制删除其(custom deleter)。这可防范 DLL 问题,可被用来自动解除互斥锁