Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57391
  • 博文数量: 20
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 282
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-20 17:23
个人简介

我的博客园;http://www.cnblogs.com/geekpaul/

文章分类

全部博文(20)

文章存档

2015年(7)

2014年(13)

我的朋友

分类: C/C++

2014-12-15 21:41:33

C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。C++中,一个参数的构造函数,承担了两个角色:一是个构造器,二是个默认且隐含的类型转换操作符。

  所以,有时候在我们写下如AAA = XXX, 这样的代码,且恰好XXX的类型正好是AAA单参数构造器的参数类型,这时候编译器就自动调用这个构造器, 创建一个AAA的对象。

关于这一点,《more effective c++》上也给出了详细的解释,例如比较Array对象,部分代码如下:
bool operator==( const Array& lhs,
const Array& rhs);
Array a(10);
Array 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参数(对于a)int(对于b[i])参数调用operator==函数,然而没有 operator==函数是这样的参数类型,我们的编译器注意到它能通过调用Array构造函数能转换int类型到Array& lt;int>类型,这个构造函数只有一个int类型的参数。然后编译器如此去编译,生成的代码就象这样:
for (int i = 0; i < 10; ++i)
      i f (a == static_cast< Array >(b[i])) ....

容易的方法是利用一个最新编译器的特性,explicit关键字。为了解决隐式类型转换而特别引入的这个特性,它的使用方法很好理解。构造函数用explicit声明,如果这样做,编译器会拒绝为了隐式类型转换而调用构造函数。显式类型转换依然合法:
template
class Array {
public:
...
explicit Array(int size); //
注意使用"explicit"
...
};
Array a(10); //
正确, explicit 构造函数, 在建立对象时能正常使用
Array b(10); //
也正确
if (a == b[i]) ... //
错误! 没有办法 隐式转换int Array

阅读(949) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~