C++ explicit关键字只能用于类内部的构造函数的声明上,且只能作用于“单个参数的构造函数”或“有多个参数,但其它参数都有默认值,只有一个参数无默认值的构造函数”,在使用被修饰后的构造函数定义对象时,无法发生相应的隐式类型转换。
隐式类型转换
在C++中,如果一个类只有一个参数的构造函数,C++允许一种特殊的声明类变量的方式,在这种情况下,可以直接将一个对应于构造函数参数类型的数据直接赋值给类变量,编译器在编译时会自动进行类型转换,将对应于构造函数参数类型的数据转换为类的对象。如下例所示:
class People
{
public:
int age;
People (int a) { age=a; }
};
void foo ( void )
{
People p1(10); //方式一
People* p_p2=new People(10); //方式二
People p3=10; //方式三
}
该例中,方式一和方式二都是平时编程过程中常用到的对象定义方式,而方式三即是特殊的方式,因为C/C++是一种强类型语言,不同的数据类型是不能随意转换的,如果要进行类型转换,必须进行显示强制类型转换,而这里,没有进行任何显示的转换,直接将一个整形数据赋值给类类变量p3。
因此,可以说,方式三中进行了一次隐式类型转换,编译器自动将对应于构造函数参数类型的数据转换为了该类的对象,因此方式三经编译器自动转换后和方式一最终的实现方式是一样的。
explicit关键字
explicit关键字的作用就是禁止隐式转换这个特性,如文章一开始而言,凡是用explicit关键字修饰的构造函数,编译时就不会进行自动转换,而会报错。如下例所示:
class A
{
A(int a);
};
int Function(A a);
当调用Function(2)的时候,2会隐式转换为A类型。这种情况常常不是程序员想要的结果,所以,要避免之,就可以这样写:
class A
{
explicit A(int a);
};
int Function(A a);
这样,当调用Function(2)的时候,编译器会给出错误信息(除非Function有个以int为参数的重载形式),这就避免了在程序员毫不知情的情况下出现错误。
注意:explicit关键字只是用于一个参数的构造函数,如:
- constructor(typename value);
- construcor(typename value1,typename value2=defaultvalue,typename value3=defaultvalue,...) ;
因为两个参数的构造函数几乎没办法隐式的转换,即无法出现classtype classname = value的情况。
参考文章
1. CSDN | cbNotes | cbNotes的专栏:不积跬步,无以至千里 | C++关键字explicit的详解和使用