`

《认清C++语言》---也谈C++关键字explicit

 
阅读更多

c++中的explicit关键字用来并且只能用来修饰类的构造函数,表明该构造函数是显式的,“显式”的意思是说创建类对象时必须写出构造函数的名称,相对的,“隐式”指的是创建类对象时不必写出构造函数名,只需根据构造函数形参类型指定实参,由编译器进行形参类型到类类型的隐式转换。

C++ Primer》指出:可以用单个实参来调用的构造函数,它自身定义了从形参类型到类类型的一个隐式转换。

也就是说,如果c++类的构造函数可以只传一个实参来调用(构造函数的形式参数实际上可能不止一个,但除了传入实参的那个参数外,其他的参数都有默认值),那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:
class ACEClass
{
public:
ACEClass( int age );

ACEClass(const std::string &name);

ACEClass(std::istream &is);
}
....

ACEClass obj(20); //ok, 显式调用构造函数
ACEClass obj2 = 20; //ok,
隐式转换,将int转换成ACEClass

String nullName = null;

ACEClass aceName = nullName; //ok, 隐式转换,将string转换成ACEClass

ACEClass aceStream = cin; //ok, 隐式转换,将std::istream转换成ACEClass
在上面的代码中编译器自动将整型转换为ACEClass类对象,实际上等同于下面的操作:

//编译器使用一个接受intACEClass构造函数从20生成一个新的ACEClass对象temp
ACEClass temp(20);

//新生成的临时对象temp被传递给obj2
ACEClass obj2 = temp;
上面的所有的操作即是所谓的"隐式转换"


有时这种隐式转换会给代码阅读者造成不必要的困惑,因此,很多时候我们要避免编译器这种自动转换的功能,这时就用到了文章开头提及的关键字explicit了。将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的ACEClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:
class ACEClass
{
public:
explicit ACEClass( int num );

explicit ACEClass(const std::string &name);

explicit ACEClass(std::istream &is);

...
}
....

ACEClass obj(20); //ok,显式调用构造函数
ACEClass obj 2= 20; //err,
不能进行隐式转换

String nullName = null;

ACEClass aceName = nullName; // err,不能进行隐式转换

ACEClass aceStream = cin; // err,不能进行隐式转换

注意:explicit关键字只能用于类内部的构造函数声明上,在类的定义体外部所作的定义上不应该再重复它:

//err.explicit allowed only on constructor declaration in class header

explicit ACEClass::ACEClass(int num)

{

...

}

这里补充说一点:explicit关键字用在具有多于一个参数的构造函数上不起作用的,因为当构造函数参数多于一个时,它默认不进行隐式类型转换。也就是说此时用不用explicit来限定构造函数都是一样的。当然,正如前面提过的,有一种例外情况,就是当调用构造函数时只传一个实参,其他参数有默认值时,此时explicit关键字仍将起它应有的作用。

MSDN中对explicit的叙述是这样的:explicit on a constructor with multiple arguments has no effect, since such constructors cannot take part in implicit conversions. However, for the purpose of implicit conversion, explicit will have an effect if a constructor has multiple arguments and all but one of the arguments has a default value.

最佳实践:通常,除非有明显的理由要定义隐式转换,否则,单形参构造函数应该声明为explicit。将构造函数设置为explicit可以避免错误,并且当转换有用时,用户可以显示的构造对象。

分享到:
评论

相关推荐

    C++关键字大全(67个).txt

    C++关键字大全(67个) asm auto bad_cast bad_typeid bool break case catch char class const const_cast continue default delete do double dynamic_cast else enum except explicit extern false finally float ...

    C++ explicit通俗解释

    C++ explicit关键字在刚学的时候就接触到了,也从各处了解了一些,但始终云里雾里,在闲来无事的时候再仔细研究了一下,自己消化理解了一下,自认为比其他网友总结的精简而不失准确。

    C++关键字详细使用

    except explicit extern false finally float for friend goto if inline int long mutable namespace new operator private protected public register reinterpret_cast return short signed sizeof static static...

    C++ Explicit关键字详细解析

    以下是对C++中Explicit关键字的用法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助

    C++中explicit作用示例代码

    C++入门学习——explicit关键字的作用,相关教程链接如下:http://blog.csdn.net/tennysonsky/article/details/49096977

    C++中的Explicit关键字

    在C++程序中很少有人去使用explicit关键字,不可否认,在平时的实践中确实很少能用的上。再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决。但稍微留心一下会发现现有的MFC库或者C++标准库中的相关类...

    Quasi-explicit-SVI

    Quasi-ExplicitCalibrationofGatheral'sSVImodel-Zeliade39、#的盖思勒尔拟显的SVI模型zeliade校准;

    C++中的explicit关键字实例浅析

    在C++程序中很少有人去使用explicit关键字,不可否认,在平时的实践中确实很少能用的上,再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决。接下来给大家介绍 C++中的explicit关键字,需要的朋友可以参考...

    C++ explicit关键字的应用方法详细讲解

    C++编程语言中有很多比较重要的关键字在实际编程中起着非常重要的作用。我们今天为大家介绍的C++ explicit关键字就是其中一个应用比较频繁的关键字。下面就让我们一起来看看这方面的知识吧。 C++ explicit关键字用来...

    认识 C++ 中的explicit 关键字

    带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:   class MyClass{ public: MyClass(int nParam);// 带一个参数的构造函数 ... //////////////////////////////

    Implicit-explicit Finite-difference Lattice Boltzmann Method for Compressible Flows

    Implicit-explicit Finite-difference Lattice Boltzmann Method for Compressible Flows,王勇,何雅玲,We propose an implicit-explicit finite-difference lattice Boltzmann method for compressible flows in ...

    An Implicit-Explicit Runge--Kutta--Chebyshev Scheme

    An Implicit-Explicit Runge--Kutta--Chebyshev Scheme for Diffusion-Reaction Equations用matlab编写的

    c/c++拷贝构造函数和关键字explicit详解

    主要介绍了c/c++拷贝构造函数和关键字explicit的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

    PyPI 官网下载 | invenio-explicit-acls-2.0.6.tar.gz

    资源来自pypi官网。 资源全名:invenio-explicit-acls-2.0.6.tar.gz

    babel-plugin-explicit-exports-references:将所有内部引用转换为模块的导出,以便每个引用均以“ module.exports”开头,而不是直接引用内部名称

    babel-plugin-explicit-exports-引用 将所有内部引用转换为模块的导出,以使每个引用module.exports开头,而不是直接引用内部名称。 这样,即使被模拟的函数在同一模块中相互调用,也可以使用Babel / TypeScript对...

    前端开源库-is-explicit

    前端开源库-is-explicit是显式的,以与对象和文本无缝工作的方式组合运算符实例和类型运算符。

    C++从零开始---入门教程

    C++从零开始(十七)——C++中的一些生僻关键字(explicit、mutable、volatile等的说 明) C++从零开始(十八)——何谓SDK(说明为什么没有放音乐的指令却依然可以编出 放音乐的程序) C++从零开始(十九)——何谓...

Global site tag (gtag.js) - Google Analytics