C++11 explicit的使用
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的使用的更多相关文章
- D3D12 图形编程
D3D 11到D3D 12的重大改进 Direct3D 12 的编程模型和 Direct3D 11大相径庭.在Direct3D 12中,应用程序和硬件靠得近多了,这在以前是从未有过的. 这让D3D12 ...
- C++面试笔记(2)
11 explicit 显式构造函数 explicit修饰的构造函数可用来防止隐式转换 class Test1 { public: Test1(int n) // 普通构造函数 { num=n; } ...
- Ubuntu16.04 ARM 编译 编译器版本和unordered_map map问题
源文件内使用unordered_map时候,例如如下demo #include <unordered_map> void foo(const std::unordered_map<i ...
- [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4) 帧类型和格式
欢迎访问我的个人网站获取更好的阅读排版体验: [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4 ...
- QT实现两条贪吃蛇
Snake.pro文件 1 #------------------------------------------------- 2 # 3 # Project created by QtCreato ...
- 地区sql
/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...
- C++ 11 多线程--线程管理
说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...
- 「C++11」Lambda 表达式
维基百科上面对于 lambda 的引入是如下描述的: 在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find.用户经常希望能够在算法函数调用的附近定义一个临时的述部函数( ...
- 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 ...
随机推荐
- 接口测试-Http状态码-postman上传文件
转自:https://www.cnblogs.com/jiadan/articles/8546015.html 一. 接口 接口:什么是接口呢?接口一般来说有两种,一种是程序内部的接口,一种是系统 ...
- 实现外卖选餐时两级 tableView 联动效果
最近实现了下饿了么中选餐时两级tableView联动效果,先上效果图,大家感受一下: 下面说下具体实现步骤: 首先分解一下,实现这个需求主要是两点,一是点击左边tableView,同时滚动右边tabl ...
- 【LeetCode】173. Binary Search Tree Iterator (2 solutions)
Binary Search Tree Iterator Implement an iterator over a binary search tree (BST). Your iterator wil ...
- Yslow---一款很实用的web性能测试插件
YSlow可以对网站的页面进行分析,并告诉你为了提高网站性能,如何基于某些规则而进行优化. YSlow可以分析任何网站,并为每一个规则产生一个整体报告,如果页面可以进行优化,则YSlow会列出具体的修 ...
- sublime Text 些许使用配置
在安装numpy等库函数时,通过“命令提示符”操作显示库函数已经安装完毕,在pycharm中可是依然显示引用失败,尝试使用sublime,显示可用,遂好好使用sublime,现配置成想用的模式. 1 ...
- 站在.NET的角度学安卓的草民笔记1
Java -> .NET 安卓 -> winform/WPF 类继承Activity -> 类继承 For ...
- MySQL子查询的优化
本文基于MySQL5.7.19测试 创建四张表,pt1.pt2表加上主键 mysql> create table t1 (a1 int, b1 int); mysql> create ta ...
- Linux软中断、tasklet和工作队列
Linux内核中的软中断.tasklet和工作队列详解 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来 ...
- IE6-IE9兼容性问题列表及解决办法:锁表头的JQuery方案和非JQuery方案(不支持IE6,7,8)
鉴于从IE8开始,IE不再支持css的expression了,所以以前依靠它完成锁表头的代码就全部失效了,面对新的浏览器,一切又要重新来过了. 现在所能找到的对于锁表头的方案主要有两种路子:一种是使用 ...
- xml中的<![CDATA[]]> 简介
被<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[<]]>表示文本内容“<”. 此标记用于xml文档中,我们先来看看使用转义符的 ...