在C++程序中很少有人去使用 explicit 关键字,不可否认,在平时的实践中确实很少能用的上。再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决。但稍微留心一下就会发现现有的MFC库或者C++标准库中的相关类声明中explicit出现的频率是很高的。了解explicit关键字的功能及其使用对于我们阅读使用库是很有帮助的,而且在编写自己的代码时也可以尝试使用。既然C++语言提供这种特性,我想在有些时候这种特性将会非常有用。
按默认规定,只用传一个参数的构造函数也定义了一个隐式转换。举个例子:
(下面这个CExample没有什么实际的意义,主要是用来说明问题)
 
//Example.h 

#pragma once 

class CExample 

{ 

public: 

CExample(void); 

public: 

~CExample(void); 

­

public: 

int m_iFirst; 

int m_iSecond; 

public: 

CExample(int iFirst, int iSecond = ); 

}; 

//Example.cpp 

#include "StdAfx.h" 

#include "Example.h" 

CExample::CExample(void) 

: m_iFirst() 

{ 

} 

CExample::~CExample(void) 

{ 

} 

CExample::CExample(int iFirst, int iSecond):m_iFirst(iFirst), m_iSecond(iSecond) 

{ 

} 

//TestExplicitKey.cpp 

...//其它头文件 

#include "Example.h" 

int _tmain(int argc, _TCHAR* argv[]) 

{ 

CExample objOne; //调用没有参数的构造函数 

CExample objTwo(, ); //调用有两个参数的构造函数 

CExample objThree(); //同上,可以传一个参数是因为该构造函数的第二个参数有默认值 

CExample objFour = ; //执行了隐式转换,等价于CExample temp(12);objFour(temp);注意这个地方调用了 

//编译器为我们提供的默认复制构造函数 

return ; 

} 

如果在构造函数声明中加入关键字explicit,如下 

explicit CExample(int iFirst, int iSecond = ); 

那么CExample objFour = ; 这条语句将不能通过编译。在vs05下的编译错误提示如下 

error C2440: 'initializing' : cannot convert from 'int' to 'CExample' 

        Constructor for class 'CExample' is declared 'explicit' 

对于某些类型,这一情况非常理想。但在大部分情况中,隐式转换却容易导致错误(不是语法错误,编译器不会报错)。
隐式转换总是在我们没有察觉的情况下悄悄发生,除非有心所为,隐式转换常常是我们所不希望发生的。
通过将构造函数声明为explicit(显式)的方式可以抑制隐式转换。也就是说,explicit构造函数必须显式调用。 引用一下Bjarne Stroustrup的例子: class String{ explicit String(int n); String(const char *p); }; String s1 = 'a'; //错误:不能做隐式char->String转换 String s2(); //可以:调用explicit String(int n); String s3 = String();//可以:调用explicit String(int n);再调用默认的复制构造函数 String s4 = "Brian"; //可以:隐式转换调用String(const char *p);再调用默认的复制构造函数 String s5("Fawlty"); //可以:正常调用String(const char *p); void f(String); ­ String g() { f(); //错误:不能做隐式int->String转换 f("Arthur"); //可以:隐式转换,等价于f(String("Arthur")); return ; //同上 }
在实际代码中的东西可不像这种故意造出的例子。
发生隐式转换,除非有心利用,隐式转换常常带来程序逻辑的错误,而且这种错误一旦发生是很难察觉的。
原则上应该在所有的构造函数前加explicit关键字,当你有心利用隐式转换的时候再去解除explicit,这样可以大大减少错误的发生。
==================
原帖地址:http://blog.csdn.net/chollima/article/details/3486230

C++中的explicit关键字 - 抑制隐式转换(转)的更多相关文章

  1. explicit 关键字 禁止隐式转换

    explicit可以抑制内置类型隐式转换,所以在类的构造函数中,使用explicit关键字,防止不必要的隐式转换

  2. explicit 只对构造函数起作用,用来抑制隐式转换。

    class A { private: int a; public: A(int x) :a(x){} void display(){ cout << a << endl; } ...

  3. C++中的隐式转换和explicit

    隐式转换 c++中的数据类型转换分为隐式转换和显示转换: 显示转换即使用static_cast等方法进行转换,相关内容请参考 <C++数据类型转换>: 隐式转换则是编译器完成的,如,boo ...

  4. C++中的explicit关键字(转)

    按默认规定,只用传一个参数的构造函数也定义了一个隐式转换.举个例子: #pragma once class CExample { public: CExample(void); CExample(); ...

  5. explicit抑制隐型转换

    本文出自 http://www.cnblogs.com/cutepig/ 按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: clas ...

  6. Scala模式匹配| 隐式转换

    1. 模式匹配 Scala中的模式匹配类似于Java中的switch语法,但是更加强大.模式匹配语法中,采用match关键字声明,每个分支采用case关键字进行声明,当需要匹配时,会从第一个case分 ...

  7. Scala入门到精通——第十九节 隐式转换与隐式參数(二)

    作者:摇摆少年梦 配套视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 隐式參数中的隐式转换 函数中隐式參数使用概要 隐式转换问题梳理 1. 隐式參数中的 ...

  8. Scala 隐式转换及应用

    什么是隐式转换 我们经常引入第三方库,但当我们想要扩展新功能的时候通常是很不方便的,因为我们不能直接修改其代码.scala提供了隐式转换机制和隐式参数帮我们解决诸如这样的问题. Scala中的隐式转换 ...

  9. 一个 MySQL 隐式转换的坑,差点把服务器整崩溃了

    我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 本来是一个平静而美好的下午,其 ...

随机推荐

  1. hdu4185

    题解:每两个联通的油井建边 然后二分图最大匹配 最后答案除以2 代码: #include<cstdio> #include<cmath> #include<cstring ...

  2. python练习题100例

    链接地址:http://www.runoob.com/python/python-100-examples.html

  3. Java IO流读写文件的几个注意点

     平时写IO相关代码机会挺少的,但却都知道使用BufferedXXXX来读写效率高,没想到里面还有这么多陷阱,这两天突然被其中一个陷阱折腾一下:读一个文件,然后写到另外一个文件,前后两个文件居然不 ...

  4. 旧书重温:0day2【5】shellcode变形记

    紧接上一篇,结合第一篇 //这篇文章主要成功溢出一个带有缓冲区溢出的小程序,其中我们的shellcode被strcpy截断了所以我们需要变形shellcode,这个实验中也出现了很多意想不到的拦路虎, ...

  5. 【vs2013】使用VS2013打包程序

    如何用 VS 2013 打包 程序? 摘自:http://www.zhihu.com/question/25415940 更多请见摘自. 答案就在这里,想要你的exe独立运行在XP中:1.将平台工具集 ...

  6. linux 系统监控某目录下文件及文件夹的变化

    inotifywait 是一个可以实时监控文件变动的工具,它利用linux内核中的inotify机制实现监控功能. 查看内核版本 [root@Oracle ~]# uname -r 2.6.32-22 ...

  7. 深入理解java虚拟机-第三章

    1.概述 2.对象已死吗? 引用计数器 给对象添加一个引用计数器,每当有引用时,计数器加1,引用失效时,计数器减1:任何时刻计数器为0的对象就是不可能再被使用的. 若对象是循环引用,则无法处理.JVM ...

  8. 21天学通C++_Day3_Part3

    控制程序流程 0.switch...case...语句中省略了break? break让程序能够退出switch结构,如果没有将继续评估后面的case语句 1.如何退出无限循环? 使用break退出当 ...

  9. c#同步調用異步(async)方法【記錄用】

    使用RestSharp中的異步方法ExecuteTaskAsync<T>編寫寫了一個異步方法,功能很簡單:異步調用API,返回結果,假設為GetAccessToken,方法簽名假設如下: ...

  10. #51单片机#超声波测距(HC-SR04)的使用方法

    #51单片机#超声波测距(HC-SR04)的使用方法