explicit的简单使用

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主要是应用于这种情况,避免出现因为隐式转换出现二意性。如下实例说明:

  1. #include <iostream>  
  2. #include <string>  
  3.   
  4. class mystring {  
  5. public:  
  6.     explicit mystring(const char* p);  
  7.     explicit mystring(int n);  
  8. };  
  9.   
  10. mystring::mystring( const char* p )  
  11. {  
  12.     std::cout << p << std::endl;  
  13. }  
  14.   
  15. mystring::mystring( int n )  
  16. {  
  17.     std::cout << n << std::endl;  
  18. }  
  19.   
  20. int main(int argc, char *argv[], char *env[])  
  21. {  
  22.     const char *c = "Hello World!!!";  
  23.     int i = 4;  
  24.   
  25.     mystring mystr1 = mystring(c);  
  26.     mystring mystr2 = mystring(i);  
  27.   
  28.     // 构造函数加上关键字explicit,下面两句编译都过不去  
  29.     // 因为此时这种隐式转换不允许  
  30.     // 所以为了避免二意义性,单参数的构造函数建议要加上explicit  
  31.     mystring mystr3 = c;    // 编译不通过,不允许隐式的转换  
  32.     mystring mystr4 = i;    // 编译不通过,不允许隐式的转换  
  33.   
  34.     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++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:

  
  
  1. class MyClass  
  2. {  
  3. public:  
  4. MyClass( int num );  
  5. }  
  6. //.  
  7. MyClass obj = 10; //ok,convert int to MyClass 

在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:

  
  
  1. MyClass temp(10);  
  2. MyClass obj = temp

上面的所有的C++ explicit关键字相关的操作即是所谓的"隐式转换"。

如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:

  
  
  1. class MyClass  
  2. {  
  3. public:  
  4. explicit MyClass( int num );  
  5. }  
  6. //.  
  7. MyClass obj = 10; //err,can't non-explict convert 

以上就是对C++ explicit关键字的相关介绍。

【编辑推荐】

  1. C++多线程测试要点总结
  2. C++定义变量使用方式简介
  3. C++命令行模式编译设置技巧分享
  4. C++托管到底是什么
  5. C++智能指针应用方式体验

在 C++ 中,`explicit` 是一个关键字,用于修饰参数的构造函数,它的作用是禁止隐式类型转换。 在默认情况下,C++ 允许编译器进行一定程度的隐式类型转换,例如将一个参数传递给一个接受相应类型参数的函数或构造函数。然而,如果你希望禁止这种隐式类型转换,可以使用 `explicit` 关键字显式声明构造函数。 下面是一个使用 `explicit` 的简单示例: ```cpp class MyClass { public: // 使用 explicit 关键字显式声明构造函数 explicit MyClass(int value) : m_value(value) {} int getValue() const { return m_value; } private: int m_value; }; void foo(const MyClass& obj) { int value = obj.getValue(); // 在这里使用 MyClass 对象 } int main() { // 使用 explicit 构造函数进行对象创建 MyClass obj1(10); // 错误!不能进行隐式类型转换 // MyClass obj2 = 20; // 正确!显式地进行类型转换 MyClass obj2 = MyClass(20); foo(obj1); return 0; } ``` 在上述示例中,`MyClass` 类有一个带有 `int` 参数的构造函数,并使用 `explicit` 关键字进行了显式声明。这意味着我们只能使用显式方式创建 `MyClass` 对象,而不能通过隐式类型转换来创建对象。因此,在 `main` 函数中,我们可以直接使用 `MyClass obj1(10)` 来创建对象,但不能使用 `MyClass obj2 = 20` 这样的隐式类型转换方式。 通过使用 `explicit` 关键字,可以避免一些意外的隐式类型转换,提高代码的可读性和明确性。它通常应用于那些可能导致意料之外行为或潜在错误的构造函数上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值