explicit 用法

以下节选自More   Effective   C++,觉得是对你的问题的一个很好的说明。建议你看看More   Effective   C++   Item   5:
        C++编译器能够在两种数据类型之间进行隐式转换(implicit   conversions),你对这些类型转换是无能为力的,因为它们是语言本身的特性。不过当你增加自己的类型时,你就可以有更多的控制力,因为你能选择是否提供函数让编译器进行隐式类型转换。有两种函数允许编译器进行这些的转换:单参数构造函数(single-argument   constructors)和隐式类型转换运算符。
单参数构造函数是指只用一个参数即可以调用的构造函数。该函数可以是只定义了一个参数,也可以是虽定义了多个参数但第一个参数以后的所有参数都有缺省值。以下有两个例子:
class   Name   {                                                                   //   for   names   of   things
public:
    Name(const   string&   s);                                           //   转换   string   到
                                                                                          //   Name
    ...    
};  
class   Rational   {                                                           //   有理数类
public:
    Rational(int   numerator   =   0,                                 //   转换int到
                      int   denominator   =   1);                           //   有理数类
    ...  
};
通过单参数构造函数进行隐式类型转换更难消除。而且在很多情况下这些函数所导致的问题要甚于隐式类型转换运算符。
举一个例子,一个array类模板,这些数组需要调用者确定边界的上限与下限:
template <class   T>
class   Array   {
public:
    Array(int   lowBound,   int   highBound);
    Array(int   size);  
    T&   operator[](int   index);  
    ...  
};
第一个构造函数允许调用者确定数组索引的范围,例如从10到20。它是一个两参数构造函数,所以不能做为类型转换函数。第二个构造函数让调用者仅仅定义数组元素的个数(使用方法与内置数组的使用相似),不过不同的是它能做为类型转换函数使用,能导致无穷的痛苦。
例如比较Array <int> 对象,部分代码如下:
bool   operator==(   const   Array <int> &   lhs,
                                  const   Array <int> &   rhs);  
Array <int>   a(10);
Array <int>   b(10);  
...  
for   (int   i   =   0;   i   <   10;   ++i)
    if   (a   ==   b[i])   {                               //   哎呦!   "a "   应该是   "a[i] "
        do   something   for   when
        a[i]   and   b[i]   are   equal;
    }
    else   {
        do   something   for   when   they 're   not;
    }
我们想用a的每个元素与b的每个元素相比较,但是当录入a时,我们偶然忘记了数组下标。当然我们希望编译器能报出各种各样的警告信息,但是它根本没有。因为它把这个调用看成用Array <int> 参数(对于a)和int(对于b[i])参数调用operator==函数,然而没有operator==函数是这样的参数类型,我们的编译器注意到它能通过调用Array <int> 构造函数能转换int类型到Array <int> 类型,这个构造函数只有一个int类型的参数。然后编译器如此去编译,生成的代码就象这样:
for   (int   i   =   0;   i   <   10;   ++i)
    if   (a   ==   static_cast <   Array <int>   > (b[i]))       ...
每一次循环都把a的内容与一个大小为b[i]的临时数组(内容是未定义的)比较。这不仅不可能以正确的方法运行,而且还是效率低下的。因为每一次循环我们都必须建立和释放Array <int> 对象
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值