C++ 中explicit关键字

explicit用来防止由单参数构造函数定义的隐式转换,但是另外一种情况例外:其中只有一个必须输入的参数,其余的为有默认值的参数。

先扫盲下什么是隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。

eg:

class things
{
    public:
        things(string &name = ""):
              m_name(name),height(0),weight(10){}
        int CompareTo(const things & other);
        string m_name;
        int height;
        int weight;
};

这里things的构造函数可以只用一个实参完成初始化。所以可以进行一个隐式转换,像下面这样:

things a;
................//在这里被初始化并使用。
string nm = "book_1";
//由于可以隐式转换,所以可以下面这样使用
int result = a.CompareTo(nm);

  这段程序使用一个string类型对象作为实参传给things的CompareTo函数。这个函数本来是需要一个tings对象作为实参。现在编译器使用string nm来构造并初始化一个

things对象,新生成的临时的things对象被传递给CompareTo函数,并在离开这段函数后被析构。

  这种行为的正确与否取决于业务需要。假如你只是想测试一下a的重量与10的大小之比,这么做也许是方便的。但是假如在CompareTo函数中 还涉及到了要除以初始化为0的height属性,那么这么做可能就是错误的。需要在构造tings之后更改height属性不为0。所以要限制这种隐式类 型转换。

  那么这时候就可以通过将构造函数声明为explicit,来防止隐式类型转换。

  explicit关键字只能用于类内部的构造函数声明上,而不能用在类外部的函数定义上。现在things类像这样:

class things
{
    public:
        explicit things(string &name = ""):
              m_name(name),height(0),weight(0){}
        int CompareTo(const things & other);
        string m_name;
        int height;
        int weight;
};

  这时再进行编译,在vs2008上会提示:没有可用于执行该转换的用户定义的转换运算符,或者无法调用该运算符。

  这时你仍然可以通过显示使用构造函数完成上面的类型转换:

things a;
................//在这里被初始化并使用。
string nm = "book_1";
//显示使用构造函数
int result = a.CompareTo(things(nm));

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

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

参考文献:

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

Explicit 关键字

时间: 2024-10-05 16:39:57

C++ 中explicit关键字的相关文章

C++中explicit关键字的作用

转自:http://www.cnblogs.com/winnersun/archive/2011/07/16/2108440.html explicit用来防止由构造函数定义的隐式转换. 要明白它的作用,首先要了解隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换. 例如: class things{ public: things(const std::string&name =""): m_name(name),height(0),weight(

C++中 explicit 关键字

阅读了 effective c++中关于初始化部分知识,其中提到了explicit关键字 explicit作用: 防止构造函数执行隐式类型转换 要明白它的作用,首先要了解隐式转换: 我们来构造一个隐式调用 方法:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换. 例如: <span style="font-size:18px;">class B{ public: B(int x); void dosomething(B bobject); }</

C++中explicit关键字的使用

看书看到了explicit关键字,就来做个笔记,讲得比较明白,比较浅. 在C++中,我们有时可以将构造函数用作自动类型转换函数.但这种自动特性并非总是合乎要求的,有时会导致意外的类型转换,因此,C++新增了关键字explicit,用于关闭这种自动特性.即被explicit关键字修饰的类构造函数,不能进行自动地隐式类型转换,只能显式地进行类型转换. 注意:只有一个参数的构造函数,或者构造函数有n个参数,但有n-1个参数提供了默认值,这样的情况才能进行类型转换. 下面通过一段代码演示具体应用(无ex

【转】C++中的explicit关键字

在C++程序中很少有人去使用explicit关键字,不可否认,在平时的实践中确实很少能用的上.再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决.但稍微留心一下就会发现现有的MFC库或者C++标准库中的相关类声明中explicit出现的频率是很高的.了解explicit关键字的功能及其使用对于我们阅读使用库是很有帮助的,而且在编写自己的代码时也可以尝试使用.既然C++语言提供这种特性,我想在有些时候这种特性将会非常有用. 按默认规定,只用传一个参数的构造函数也定义了一个隐式转换.举

C++中的explicit关键字的用法

一.explicit作用: 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换. 二.explicit使用注意事项: explicit 关键字只能用于类内部的构造函数声明上. explicit 关键字作用于单个参数的构造函数. 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换 参考博客:http://www.cnblogs.com/this-54327365

C++中的explicit关键字(转)

按默认规定,只用传一个参数的构造函数也定义了一个隐式转换.举个例子: #pragma once class CExample { public: CExample(void); CExample(int iFirst, int iSecond = 4); ~CExample(void); public: int m_iFirst; int m_iSecond; }; #include "StdAfx.h" #include "Example.h" CExample:

C++ 中的explicit关键字

explicit关键字在c++中是为了防止隐式转换 (1) explicit 此关键字只能对用户自己定义的对象起作用,不对默认构造函数起作用此关键字只能够修饰构造函数.而且构造函数的参数只能有一个.. (2)何时用explicit 当我们不希望自动类型转换的时候用,其实标准库好多构造函数都是explicit的 比如说vector <int> ivec(10);  //这种定义看起来一目了然 不能写成vector <int> ivec=10://此种定义让程序员感到疑惑 (3)何时不

深入理解C++中的explicit关键字

深入理解C++中的explicit关键字 [email protected] http://blog.csdn.net/kezunhai C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式). 关于explicit关键字,先看看MSDN上的解释: This keyword is a declaration speci

C++中显式、隐式与explicit关键字

在Qt的开发中看到explicit,由此展开搜索. 隐式:编译器完成的转换,如 int a = 1; float b = 3; float sum; sum = a + b; //a本是int,编译器将a隐式地转化为了float 显式:用户完成的转换,如 float a=1; float b=3; int s; s = (int)a+(int)b;//a与b被显式地转化为了float 对于函数而非数据,这里有另一个例子[引用]: #include <iostream> using namesp