C++的explicit关键字

C++程序员对于explicit这个关键字其实不是很熟悉,至少我是如此;原因在于其使用范围不大,而且作用也没有那么大。
但是这不是说明我们的程序中不需要这个关键字,按Google的C++编程规范和Effective C++的推荐看,我们最好将只有一个参数的构造函数都加上这个关键字,这同时也是cppcheck的要求。

explicit意味着明确的,确定的,这表明这个构造函数是无法隐式转换的,其反义词正式implicit。没有了隐式转换,我们则需要显式使用某个类型的构造函数,如此,可以规避很多不那么能拿得出手的外部类的调用。

指定构造函数或转换函数(从c++ 11开始)是显式的,也就是说,它不能用于隐式转换和复制初始化

一个构造函数只有一个非默认参数(从c++ 11开始),没有explicit声明的,称为转换构造函数。

我们来看一个使用explicit 的代码


class explicitConstruct
{
public:
    explicitConstruct();
    explicitConstruct(int i){
    	std::cout << "we use interger parameter is "<<i <<"\n";
    }
    explicitConstruct(int i,int j) {
    	std::cout << "we use double interger parameter is "<<i<<" and "<<j<<"\n";
    }

};

class explicitConstructB
{
public:
    explicit explicitConstructB(int i){
    	std::cout << "we use explicit explicitConstructB interger parameter is "<<i <<"\n";
    }
    explicit explicitConstructB(int i,int j){
    	std::cout << "we use explicit explicitConstructB double interger parameter is "<<i<<" and "<<j<<"\n";
    }
	
};
};

explicitConstruct和explicitConstructB类的唯一区别是explicitConstructB的构造函数加入了explicit。
以下是测试代码

explicitConstruct i(3);//ok
explicitConstruct j(3,4); //ok
explicitConstructB ii(3);//ok
explicitConstructB jj(3,4);//ok

explicitConstruct k = 3;//ok
explicitConstruct l = {3,4};//ok

// explicitConstructB kk = 3; //error! copy-initialization does not consider explicitConstructB::explicitConstructB(int)
// explicitConstructB ll = {3,4};///error! copy-initialization does not consider explicitConstructB::explicitConstructB(int,int)
explicitConstructB kkk = explicitConstructB(3);//ok
explicitConstructB lll = explicitConstructB(3,4);//ok

测试代码很清楚的说明了explicit关键字发挥的作用,即让类对象的构造过程无法使用隐式转换的方式调用拷贝初始化。这样做的好处在于,我们可以严格控制构造器参数的类型,避免发生歧义。

posted @ 2018-12-09 16:40  Lckfa  阅读(332)  评论(0编辑  收藏  举报