接口的设计(让类被正确的使用)——《Effective c++》

要开发一个不容易被误用的类,我们就要首先考虑用你的类的用户可能会犯怎样的错误


//首先介绍一下explicit
//考虑如下代码:
class String {
String ( int n ); //本意是预先分配n个字节给字符串
String ( const char* p ); // 用C风格的字符串p作为初始化值
...
}

String s2 ( 10 );   //OK 分配10个字节的空字符串
String s3 = String ( 10 ); //OK 分配10个字节的空字符串


String s4 = 10; //编译通过,也是分配10个字节的空字符串
String s5 = ‘a’; //编译通过,分配int(‘a’)个字节的空字符串


//s4 和s5 分别把一个int型和char型,隐式转换成了分配若干字节的空字符串,容易令人误解。
//为了避免这种错误的发生,我们可以声明显示的转换,使用explicit 关键字,这样,后面的两个操作将不会被编译通过
//explicit 预防出现隐式转换
struct Day{
    explicit Day(int d) :val(d){};
    int val;
};
struct Month{
    explicit Month(int m) :val(m){};
    int val;
};
struct Year{
    explicit Year(int y) :val(y){};
    int val;
};
class Date{

private:
    Year _year;
    Month _month;
    Day _day;
public:
    Date(const  Month& mon, const  Day& day, const  Year& year) :_year(year), _month(mon), _day(day){};


};
int  main(){

    //  Date d(1,4,5);  //错误
    //  Date d(Month(5),Year(2015),Day(25));  //错误
      Date d(Month(5),Day(25),Year(2015));  //正确
      //防止用户不小心误用
    system("pause");
    return 0;
}

//为了防止用户输入的Date符合标准,比如一年只有十二个月,我们也可以这样设计class Month(其他的如每月的天数同样可以如此)
class Month{
public:
    static Month Jan(){ return Month(1); };
    //...
    explicit Month(int m) :val(m){};
private:
    int val;
};
//然后用户调用接口时,就只能写这样的代码:
Date d(Month::Jan(), Day(25), Year(2015));  //正确
//规范用户的行为,为用户考虑到所有可能犯错的方面
//当然,以上的例子太过于理想化了,但是这个思想是可以借鉴的。就这样
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值