c++提供了关键字explicit,禁止通过构造函数进行的隐式转换。声明为explicit的构造函数不能在隐式转换中使用。
- explicit用于修饰构造函数,防止隐式转化。
- 是针对单参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造)而言。
class String
{
public:
String(int n)
{
cout << "有参构造函数" << endl;
}
String(const char *p)
{
cout << "拷贝构造函数" << endl;
}
};
String string1(10); // OK
String string2 = 10; // OK
String string3; // Err, 因为没有默认构造函数
String string4("aaaa"); // OK
String string5 = "bbb"; // OK
String string6 = 'c'; // OK
string1 = 2; // OK
string2 = 3; // OK
string3 = string1; // OK, 至少编译是没问题的, 但是如果析构函数里用free释放_pstr内存指针的时候可能会报错, 完整的代码必须重载运算符"=", 并在其中处理内存释放
"String string2 = 10;" 在C++中, 如果的构造函数只有一个参数时, 那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象. 也就是说 "String string2 = 10;" 这段代码, 编译器自动将整型转换为String类对象, 实际上等同于下面的操作:
String string2(10);
或
String temp(10);
String string2 = temp;
上述代码中的
String string2 = 10;
String string5 = "bbb";
String string6 = 'c';
到底是调用还是赋值呢?这影响了代码的可读性,而且容易让人感到疑惑,为了防止这种现象的发生,于是有了explicit关键字
class String
{
public:
explicit String(int n)
{
cout << "有参构造函数" << endl;
}
String(const char *p)
{
cout << "拷贝构造函数" << endl;
}
};
String string2 = 10; // Err
String string5 = "bbb"; // Err
String string6 = 'c'; // Err
explicit关键字的作用就是防止类构造函数的隐式自动转换.
注意:explicit关键字只对有一个参数的类构造函数有效, 如果类构造函数参数大于或等于两个时, 是不会产生隐式转换的, 所以explicit关键字也就无效了.
class String
{
public:
explicit String(int n,int m)
{
cout << "有参构造函数" << endl;
}
String(const char *p)
{
cout << "拷贝构造函数" << endl;
}
};
但如果只传入一个参数时,explicit依旧有效
explicit String(int n,int m = 0)
{
cout << "有参构造函数" << endl;
}