http://blog.csdn.net/huang_xw/article/details/7908917
http://www.programlife.net/cpp-explicit-keyword.html
http://developer.51cto.com/art/201002/183398.htm
按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,Explicit主要是应用于这种情况,避免出现因为隐式转换出现二意性。如下实例说明:
- #include <iostream>
- #include <string>
- class mystring {
- public:
- explicit mystring(const char* p);
- explicit mystring(int n);
- };
- mystring::mystring( const char* p )
- {
- std::cout << p << std::endl;
- }
- mystring::mystring( int n )
- {
- std::cout << n << std::endl;
- }
- int main(int argc, char *argv[], char *env[])
- {
- const char *c = "Hello World!!!";
- int i = 4;
- mystring mystr1 = mystring(c);
- mystring mystr2 = mystring(i);
- // 构造函数加上关键字explicit,下面两句编译都过不去
- // 因为此时这种隐式转换不允许
- // 所以为了避免二意义性,单参数的构造函数建议要加上explicit
- mystring mystr3 = c; // 编译不通过,不允许隐式的转换
- mystring mystr4 = i; // 编译不通过,不允许隐式的转换
- return 0;
- }
第一次遇见explicit,那是在《The C++ Standard Library》里面,全然不明白什么意思。如今,这本书已经翻完了,看起了《Generic Programming And Standard Templete Library》,感觉看后台实现比前台应用好玩多了,但是看GP&STL还是需要一定基础的,我只好又翻起了《C++ Primer》。这次再次遇到explicit,该做个了断了。
其实explicit主要用于防止隐式转换,用于修饰构造函数、复制构造函数。比如,下面的代码编译不会出错:
#include <iostream>
using namespace std;
class Demo
{
private:
int value;
public:
Demo():value(0){}
Demo(int val):value(val){}
Demo(const Demo& d):value(d.value){}
};
int main()
{
Demo d = 1;
Demo dd = d;
return 0;
}
Demo d = 1会这样运行:通过将1传递给单个形参构造函数,用这个构造函数来初始化对象d。对于下一行代码,通过将d传递给复制构造函数,来初始化dd。这些隐式调用都是自动完成的。有时候运行的很好,但是也有的时候会造成出乎意外的结果。能不能防止隐式调用呢?可以的。explicit就是用作这个用途的。当在构造函数和复制构造函数前面都加上explicit时,编译就会出错,下面的写法才是正确的:
#include <iostream>
using namespace std;
class Demo
{
private:
int value;
public:
Demo():value(0){}
//explicit能防止以赋值语法带有转型操作的初始化
explicit Demo(int val):value(val){}
explicit Demo(const Demo& d):value(d.value){}
};
int main()
{
//Demo d = 1; //构造函数加上explicit时错误
Demo d(10);
//Demo dd = d; //赋值构造函数加上explicit时错误
Demo dd(d);
return 0;
}
C++编程语言中有很多比较重要的关键字在实际编程中起着非常重要的作用。我们今天为大家介绍的C++ explicit关键字就是其中一个应用比较频繁的关键字。下面就让我们一起来看看这方面的知识吧。
C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?
如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:
- class MyClass
- {
- public:
- MyClass( int num );
- }
- //.
- MyClass obj = 10; //ok,convert int to MyClass
在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:
- MyClass temp(10);
- MyClass obj = temp;
上面的所有的C++ explicit关键字相关的操作即是所谓的"隐式转换"。
如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:
- class MyClass
- {
- public:
- explicit MyClass( int num );
- }
- //.
- MyClass obj = 10; //err,can't non-explict convert
以上就是对C++ explicit关键字的相关介绍。
【编辑推荐】