您的位置:首页 > 编程语言 > C语言/C++

Effective C++——条款18(第4章)

2015-09-04 18:24 309 查看

第4章 设计与声明

Designs and Declarations

所谓软件设计,是"令软件做出希望它做的事情"的步骤和做法,通常以颇为一般性的构想开始,最终演变成十足的细节,以允许特殊接口(interfaces)的开发.这些接口而后必须转换为C++声明式.最重要,最适合的一个准则是:"让接口容易被正确,不容易被误用".

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

Make interfaces easy to use correctly and hard to use incorrectly



function接口,class 接口,template 接口...每一种接口都是客户与代码互动的手段.欲开发一个"容易被正确使用,不容易被误用"的接口,首先必须考虑客户可能做出什么样的错误.假设为一个用来表现日期的 class 设计构造函数:

class Date {
public:
    Date(int month, int day, int year);
    ...
};
乍看之下这个接口通情达理,但它的客户很容易犯下至少两个错误,第一,他们也许会以错误的次序传递参数:

Date d(30, 3, 1995);            // error!应该是"3,30"而不是"30,3"
第二,他们可能传递一个无效的月份或天数:

Date d(2, 30, 1995);            // error!应该是"3,30"而不是"2,30"
许多客户端错误可以因为导入新类型而获得预防.在防范"不值得拥有的代码"上,类型系统是很好的办法.下面导入简单的外覆类型来区分天数,月份和年份,然后于Date构造函数中使用这些类型:

struct Day {
    explicit Day(int d) : val(d) {}
    int day;
};
struct Month {
    explicit Month(int m) : val(m) {}
    int val;
};
struct Year {
    explicit Year(int y) : val(y) {}
    int val;
};
class Date {
public:
    Date(const Month &m, const Day &d, const Year &y);
    ...
};
Date d(30, 3, 1995);                        // error!
Date d(Day(30), Month(3), Year(1995));        // error!
Date d(Month(3), Day(30), Year(1995));        // OK!
令Day, Month和Year成为成熟且充分锻炼的 class 并封装其内部数据,比简单使用上述的 struct 好(详见条款22).

一旦正确的类型就定位,限制其值有时候是合理的.例如:

class Month {
public:
    static Month Jan() { return Month(1); }        // 函数,返回有效月份
    ...                                            // 这些是函数而非对象
    static Month Dec() { return Month(12); }
private:
    explicit Month(int m);                        // 阻止生成新的月份
    ...
};
Date d(Month::Mar(), Day(3), Year(1995));
如果"以函数替换对象,表现某个特定月份"让人感觉诡异,但是考虑到non-local static 对象的初始化次序有可能出问题(详见条款4),就感觉合理了.

预防客户错误的另一个办法是,限制类型内什么事可做,什么事不能做.常见的限制就是加上 const.例如条款3曾经说明为什么"以const修饰operator*的返回类型"可阻止客户因"用户自定义类型"而犯错:

if (a * b = c) ...
一个一般性的准则是"尽量令自定义types的行为与内置types一致".

注意:

好的接口很容易被正确使用,不容易被误用.应该在所有接口中努力达成这些性质.

"促进正确使用"的办法包括接口的一致性,以及与内置类型的行为兼容.

"阻止误用"的办法包括建立新类型,限制类型上的操作,束缚对象值,以及消除客户的资源管理责任.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: