C++提供关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。
声明为explicit的构造函数不能在隐式转换中使用,即只能显式调用构造函数。
(1)只适用于只有一个参数的构造函数,或者第一个参数无默认值,其余参数有默认值的构造函数。
(2)对于复制构造函数也有此作用。
(2)意义在于,在不经意的赋值时,隐式的转换构造函数可能会造成逻辑错误,避免这种情况,就需要规定为显式。
声明为explicit的构造函数不能在隐式转换中使用,即只能显式调用构造函数。
(1)只适用于只有一个参数的构造函数,或者第一个参数无默认值,其余参数有默认值的构造函数。
(2)对于复制构造函数也有此作用。
(2)意义在于,在不经意的赋值时,隐式的转换构造函数可能会造成逻辑错误,避免这种情况,就需要规定为显式。
(3)JAVA中提供自动装箱(autoboxing)、拆箱(unboxing)的功能。
一般我们要创建一个类的对象实例的时候,我们会这样: Class a = new Class(parameter);
当我们创建一个Integer对象时,却可以这样: Integer i = 100;
实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = Integer.valueOf(100);
即便没有explicit系统的自行转换也能解决问题。
再顺便提一下:
String str1="abc" 可能创建一个对象或者不创建对象,如果"abc"这个字符串在javaString池里不存在,会在javaString池创建这个一个String对象("abc").如果已经存在,str1直接reference to这个String池里的对象。
String str2 = new String("abc") 至少创建一个对象,也可能两个。因为用到new关键字,会在heap创建一个 str2 的String 对象,它的value 是 "abc".同时,如果"abc"这个字符串在javaString池里不存在,会在java String池创建这个一个String对象("abc").可以知道java中直接赋值于new创建对象在内存中的位置是不同的。
#include using namespace std; class A { public: A(int n) { x=n; }//普通构造函数 private: int x; }; class B { public: explicit B(int n) { y=n; }//explicit(显式)构造函数 private: int y; }; class C { public: explicit C(int m,int n)//多参数构造函数 { x = m; y = n; } private: int x,y; }; class D { public: explicit D(int m,int n=0)//多参数构造函数带默认值 { x = m; y = n; } private: int x,y; }; class E { public: E(int m,int n=0)//普通多参数构造函数带默认值 { x = m; y = n; } private: int x,y; }; class F { public: explicit F(int m)//explicit(显式)构造函数 { x = m; } explicit F(F &p)//explicit(显式)复制构造函数 { x = p.getX(); } int getX() { return x; } private: int x; }; int main() { A t1=12;//隐式调用其构造函数,成功 //B t2=12;//编译错误,不能隐式调用其构造函数 B t2(12);//显式调用成功 C t3(12,12);//只能显式调用。explicit无效 //D t4=12;//编译错误,不能隐式调用其构造函数 D t4(12);//显式调用成功 E t5=12;//隐式调用其构造函数,成功 F t6(12);//只能显式调用 //F t7=t6;//编译错误,不能隐式调用其复制构造函数 F t8(t6);//显式调用复制构造函数,成功 return 0; }