C++中的explicit关键字只能用于修饰只有一个参数的类构造函数 , 它的作用是表明该构造函数是显示的, 而非隐式的,跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下为implicit(隐式)。

关于explicit关键字,先看看MSDN上的解释:

This keyword is a declaration specifier that can only be applied to in-class constructor declarations . An explicit constructor cannot take part in implicit conversions. It can only be used to explicitly construct an object 。

从上面的解释可以看到, explicit关键字的作用: 禁止隐式调用类内的单参数构造函数, 这主要包括如下三层意思:

  (1)该关键字只能用来修饰类内部的构造函数

  (2)禁止隐式调用拷贝构造函数

  (3)禁止类对象之间的隐式转换

首先,来看看隐式转换,如下例:

#include <iostream>

using namespace std;

class CExplict
{
public:
CExplict( bool _explicit)
{
this->is_explict = _explicit;
} CExplict(const CExplict& other)
{
this->is_explict = other.is_explict;
} friend void printExplicit(const CExplict& cx); private:
bool is_explict;
}; void printExplicit(const CExplict& cx)
{
cout<<"is_explict="<<cx.is_explict<<endl;
} int main( int argc, char* argv[])
{
CExplict cx1{};
CExplict cx2{3.14};
CExplict cx3 = false;
printExplicit(cx1);
printExplicit(cx2);
printExplicit(cx3);
printExplicit(false);
printExplicit(3.14);
return ;
}

奇怪吗?但是程序可以正常执行,隐式调用CExplict类的单参数构造函数,这种调用在C++语法中是允许的。编译器首先会以true构造一个临时对象,在将此临时对象通过赋值构造函数赋值给cx1。但是诸如:CExplict cx1{1}和printExplicit(false)这种表达形式看着很别扭,也很让人费解,将一个bool型的值赋给一个CExplicit类的cx1,使代码的可读性变差。

因此,为了禁止对类的单参数构造函数的隐式调用,C++引入了关键字explicit。在类的定义中,在任何一个单参数构造函数钱加explicit关键字,就可以禁止对该构造函数的隐式调用。

在CExplict构造函数前添加explicit,在执行上面一段代码,则会报:

error C2440: “初始化”: 无法从“bool”转换为“CExplict”的错误,为了使程序能正确运行,需要将main函数内的代码改为:

int main( int argc, char* argv[])
{
CExplict cx1 = CExplict(true);
CExplict cx2 = cx1;
printExplicit(cx1);
printExplicit(cx2);
printExplicit(CExplict(false));
return ;
}

总结:

  (1)explicit关键字只需用于类内的单参数构造函数前面。由于无参数的构造函数和多参数的构造函数总是显示调用,这种情况在构造函数前加explicit无意义。

  (2)如果想禁止类A对象被隐式转换为类B对象,可在类B中使用关键字explicit。

  

  google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明称explicit。例如作为其他类的透明包装器的类。

  effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期的类型转换,除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit.鼓励大家遵循相同的政策。

C++11 explicit的使用的更多相关文章

  1. D3D12 图形编程

    D3D 11到D3D 12的重大改进 Direct3D 12 的编程模型和 Direct3D 11大相径庭.在Direct3D 12中,应用程序和硬件靠得近多了,这在以前是从未有过的. 这让D3D12 ...

  2. C++面试笔记(2)

    11 explicit 显式构造函数 explicit修饰的构造函数可用来防止隐式转换 class Test1 { public: Test1(int n) // 普通构造函数 { num=n; } ...

  3. Ubuntu16.04 ARM 编译 编译器版本和unordered_map map问题

    源文件内使用unordered_map时候,例如如下demo #include <unordered_map> void foo(const std::unordered_map<i ...

  4. [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4) 帧类型和格式

    欢迎访问我的个人网站获取更好的阅读排版体验: [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4 ...

  5. QT实现两条贪吃蛇

    Snake.pro文件 1 #------------------------------------------------- 2 # 3 # Project created by QtCreato ...

  6. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  7. C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  8. 「C++11」Lambda 表达式

    维基百科上面对于 lambda 的引入是如下描述的: 在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find.用户经常希望能够在算法函数调用的附近定义一个临时的述部函数( ...

  9. Effective Modern C++ 42 Specific Ways to Improve Your Use of C++11 and C++14

    Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understa ...

随机推荐

  1. ios中coredata

    http://blog.csdn.net/q199109106q/article/details/8563438 // // MJViewController.m // 数据存储5-Core Data ...

  2. c++ ado 程序终止时崩溃

    在_ConnectionPtr析构的时候要将_ConnectionPtr置NULL ADODB::_ConnectionPtr conn;conn.CreateInstance(__uuidof(AD ...

  3. 网络编程学习笔记一:Socket编程

    “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...

  4. 简单几步让CentOS系统时间同步(转)

    在使用CentOS系统的时候,我们可能会遇到时间不准的问题,那我们如何解决这个我问题呢,下面就来教大家一个CentOS系统时间同步的方法,希望大家可以解决自己所存在的疑问. CentOS系统时间同步的 ...

  5. 【Android】Android解析短信操作

    目录结构: contents structure [-] 获取短信 发送短信 1.获取短信 在AndroidManifest.xml中,添加权限: <uses-permission androi ...

  6. 【MySQL】MySQL支持的数据类型

    1.整型 MySQL数据类型 含义(有符号) tinyint(m) 1个字节 范围(-128~127) smallint(m) 2个字节 范围(-32768~32767) mediumint(m) 3 ...

  7. mysql主从复制配置问题

    一,基本步骤 1,创建在主从数据上都创建复制账号,权限选上super, replication slave , replication master(选上这个可以方便从库变成主库): 2,配置主库和备 ...

  8. 从语句 char* p="test" 说起

    我相信,使用C/C++多年的人对下面这个字符串赋值语句都不会陌生吧.                 char* p = "test";   同时,我也相信,各位在使用这种语句后吃 ...

  9. [转]Spring Boot应用的后台运行配置

    转自:http://blog.didispace.com/spring-boot-run-backend/ 酱油一篇,整理一下关于Spring Boot后台运行的一些配置方式.在介绍后台运行配置之前, ...

  10. Jedis工具类(含分布式锁的调用和释放)

    个人把工具类分为两部分: 一.连接池部分 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.j ...