C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?

如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:

  1. class MyClass
  2. {
  3. public:
  4. MyClass( int num );
  5. }
  6. //.
  7. MyClass obj = 10; //ok,convert int to MyClass

在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:

  1. MyClass temp(10);
  2. MyClass obj = temp;

上面的所有的C++ explicit关键字相关的操作即是所谓的"隐式转换"。

如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:

  1. class MyClass
  2. {
  3. public:
  4. explicit MyClass( int num );
  5. }
  6. //.
  7. MyClass obj = 10; //err,can't non-explict convert

以上就是对C++ explicit关键字的相关介绍。

按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示:
class String {
String ( const char* p ); // 用C风格的字符串p作为初始化值
//…
}
String s1 = “hello”; //OK 隐式转换,等价于String s1 = String(“hello”);
 
但是有的时候可能会不需要这种隐式转换,如下:
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 关键字:
class String {
       explicit String ( int n ); //本意是预先分配n个字节给字符串
String ( const char* p ); // 用C风格的字符串p作为初始化值
//…
}
加上explicit就抑制了String ( int n )的隐式转换,
 
下面两种写法仍然正确:
String s2 ( 10 );   //OK 分配10个字节的空字符串
String s3 = String ( 10 ); //OK 分配10个字节的空字符串
 
下面两种写法就不允许了:
String s4 = 10; //编译不通过,不允许隐式的转换
String s5 = ‘a’; //编译不通过,不允许隐式的转换
 
因此,某些时候,explicit 可以有效得防止构造函数的隐式转换带来的错误或者误解

----------------------------------------------------------
explicit   只对构造函数起作用,用来抑制隐式转换。如:   
  class   A   {   
          A(int   a);   
  };   
  int   Function(A   a);   
    
  当调用   Function(2)   的时候,2   会隐式转换为   A   类型。这种情况常常不是程序员想要的结果,所以,要避免之,就可以这样写:   
    
  class   A   {   
          explicit   A(int   a);   
  };   
  int   Function(A   a);   
    
  这样,当调用   Function(2)   的时候,编译器会给出错误信息(除非   Function   有个以   int   为参数的重载形式),这就避免了在程序员毫不知情的情况下出现错误。

总结:explicit   只对构造函数起作用,用来抑制隐式转换。

参考:
http://blog.csdn.net/smilelance/archive/2007/03/14/1528737.aspx
http://topic.csdn.net/t/20040509/15/3046021.html

c++ explicit的更多相关文章

  1. 可空类型(Nullable<T>)及其引出的关于explicit、implicit的使用

    问题一:Nullable<T>可赋值为null 先看两行C#代码 int? i1 = null; int? i2 = new int?(); int? 即Nullable<int&g ...

  2. 关于Django 错误 doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS

    记录一下 报错 doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS\ 这个问题出现没 ...

  3. 显示转换explicit和隐式转换implicit

    用户自定义的显示转换和隐式转换 显式转换implicit关键字告诉编译器,在源代码中不必做显示的转型就可以产生调用转换操作符方法的代码. 隐式转换implicit关键字告诉编译器只有当源代码中指定了显 ...

  4. explicit抑制隐型转换

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

  5. C++ explicit关键字详解

    本文系转载,原文链接:http://www.cnblogs.com/ymy124/p/3632634.html 首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用 ...

  6. Implicit and Explicit Multithreading MULTITHREADING AND CHIP MULTIPROCESSORS

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION The concept of thread ...

  7. 【Android 疑难杂症1】android.content.ActivityNotFoundException: Unable to find explicit activity class

    android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.cnote ...

  8. C++笔记(1)explicit构造函数

    按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: class String { String ( const char* p );  ...

  9. C++中explicit关键字的使用

    看书看到了explicit关键字,就来做个笔记,讲得比较明白,比较浅. 在C++中,我们有时可以将构造函数用作自动类型转换函数.但这种自动特性并非总是合乎要求的,有时会导致意外的类型转换,因此,C++ ...

  10. 错误:Implicit super constructor xx() is undefined for default constructor. Must define an explicit constructor

    错误:Implicit super constructor xx() is undefined for default constructor. Must define an explicit con ...

随机推荐

  1. configure JDBCRealm JAAS for mysql and tomcat 7 with form based authentication--reference

    Hello all, In this tutorial we are going to configure JDBCRealm JAAS for tomcat 7 and mysql database ...

  2. viewpager+fragment学习笔记

    有暇,总结一下viewpager+fragment的使用. 先来看看效果图: 有三个标题,三个fragment,滑动时标题的颜色会随着变化. MainActivity.java public clas ...

  3. oracle 异常管理

    命名的系统异常                  产生原因 access_into_null 未定义对象 CASE_NOT_FOUND CASE 中若未包含相应的 WHEN ,并且没有设置 ELSE ...

  4. Oracle 卸载 不干净

    关闭oracle相关的服务 注册表删除(可能因为oracle及windows的版本不同注册表信息也有些差异): 开始è输入regedit 打开注册表编辑器删除下面的目录 HKEY_LOCAL_MACH ...

  5. [原创] SQLite数据库使用清单(下)

    上文两章对SQLite的功能.语法.和操作进行了介绍,本文讲解SQLite的一些高级语法和操作. 3.

  6. Android开发文摘集合1

    作者:张明云 原标题:Android 开发中,有哪些坑需要注意? 作者github主页:zmywly8866.github.io/ 在Android library中不能使用switch-case语句 ...

  7. 使用AutoMapper实现Dto和Model之间自由转换

    应用场景:一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转 ...

  8. C# DateTime

    //c datetime 格式化DateTime dt = DateTime.Now;Label1.Text = dt.ToString();//2005-11-5 13:21:25Label2.Te ...

  9. 微信小程序开发之入门篇(熟悉项目结构)

    微信小程序创建之后会生成一个项目模板,如下图所示(基本如此,但并不局限于此) 现在分别来说明一下每个文件及目录的意思 app.js 程序的入口文件,必须存在. app.js是小程序的脚本代码.我们可以 ...

  10. WebService开发步骤

    WebService原理什么的百度很多我就说了,无非就是提供一个接口放在服务端,客户端实现这个接口就可以拿到自己需要的东西. 现在简单说一下用myEclipse来实现服务端和客户端.另一种WebSer ...