1、C++中的关键字explicit主要是用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。类构造函数默认情况下声明为隐式的即implicit。隐式转换即是可以由单个实参来调用的构造函数定义了一个从形参类型到该类类型的隐式转换。编译器在试图编译某一条语句时,如果某一函数的参数类型不匹配,编译器就会尝试进行隐式转换,如果隐式转换后能正确编译,编译器就会继续执行编译过程,否则报错。
2、explicit关键字只能用于类内部的构造函数声明上,而不能用在类外部的函数定义(函数实现)上,它的作用是不能进行隐式转换;explicit关键字作用于单个参数的构造函数,如果构造函数有多个参数,但是从第二个参数开始,如果各参数均有默认赋值,也可以应用explicit关键字。
3、 当构造函数只有一个参数时,会进行自动隐式转换,当构造函数参数个数超过或等于两个时自动取消隐式转换,当只有一个必须输入的参数,其余的为有默认值的参数时使用explicit也起作用。
4、一般只将有单个参数的构造函数声明为explicit,而拷贝构造函数不要声明为explicit。explicit关键字只能对用户自己定义的对象起作用,不对默认构造函数起作用。此关键只能够修饰构造函数。无参数的构造函数和多参数的构造函数总是显示调用,这种情况在构造函数前加explicit无意义。
5、当不希望进行自动类型转换时用explicit,标准库的许多构造函数都是explicit的。
我们通过例子来直观的说明:
#include <iostream>
using namespace std;
class A
{
public:
A(int i = 5)
{
m_a = i;
}
private:
int m_a;
};
int main()
{
A s;
//我们会发现,我们没有重载'='运算符,但是却可以把内置的int类型赋值给了对象A.
s = 10;
//实际上,10被隐式转换成了下面的形式,所以才能这样.
//s = A temp(10);
system("pause");
return 0;
}
此时,我们发现s的成员变量m_a已将被更改了。
看看我们在类A的构造函数前加上explicit关键字会发生什么。
#include <iostream>
using namespace std;
class A
{
public:
//这里用explicit关键词来修饰类构造函数.
explicit A(int i = 5, int j = 10)
{
m_a = i;
m_b = j;
}
private:
int m_a;
int m_b;
};
int main()
{
A s;
//这样直接赋值,会被提示错误,因为explicit抑制隐式转换的进行
s = 10;//这样会报错!!!
//当然显示转换还是可以的.
s = A(20);
system("pause");
return 0;
}
再来看一个例子。
#include <iostream>
using namespace std;
class Test1
{
public :
Test1(int num):n(num){}
private:
int n;
};
class Test2
{
public :
explicit Test2(int num):n(num){}
private:
int n;
};
int main()
{
Test1 t1 = 12;
Test2 t2(13);
Test2 t3 = 14;
return 0;
}
编译时t3那一行会报错:提示:无法从“int”转化为“Test2”。注释掉t3那一行,t1能编译通过,调试时发现t1中的成员变量n已被赋值成功。
通过以上两个例子我们可得:对于仅有一个参数或除第一个参数外其余参数均有默认值的类构造函数,尽可能使用explicit关键字修饰。
另注意:当类的构造函数的声明和定义分别在两个文件里时,explicit只能写在构造函数的声明中,不能写在定义中。
如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810