【C++关键字】 explicit
在 C++ 中,explicit
关键字用于构造函数或转换函数,以防止隐式转换。它告诉编译器该构造函数或转换函数只能通过直接调用来使用,而不能通过隐式转换来使用。
使用 explicit
的示例
构造函数
默认情况下,单参数的构造函数可以用于隐式转换。考虑以下代码:
#include <iostream>
class MyClass {
public:
MyClass(int x) {
std::cout << "Constructor called with " << x << std::endl;
}
};
void doSomething(MyClass obj) {
// ...
}
int main() {
doSomething(42); // Implicitly converts 42 to MyClass object
return 0;
}
在上面的代码中,doSomething(42)
将 42
隐式地转换为一个 MyClass
对象。这是因为 MyClass
的构造函数接受一个 int
参数,因此可以进行这种隐式转换。
为了防止这种隐式转换,我们可以使用 explicit
关键字:
#include <iostream>
class MyClass {
public:
explicit MyClass(int x) {
std::cout << "Constructor called with " << x << std::endl;
}
};
void doSomething(MyClass obj) {
// ...
}
int main() {
// doSomething(42); // Error: no matching function for call to 'doSomething(int)'
MyClass obj(42);
doSomething(obj); // Correct way to call it
return 0;
}
在这个版本中,doSomething(42)
将导致编译错误,因为 MyClass
的构造函数被标记为 explicit
,这意味着它不能用于隐式转换。我们必须显式地创建一个 MyClass
对象来调用 doSomething
。
转换运算符
explicit
关键字也可以用于转换运算符。考虑以下代码:
#include <iostream>
class MyClass {
public:
operator int() const {
return 42;
}
};
void printInt(int x) {
std::cout << x << std::endl;
}
int main() {
MyClass obj;
printInt(obj); // Implicitly converts MyClass object to int
return 0;
}
在上面的代码中,printInt(obj)
将 obj
隐式地转换为 int
类型。这是因为 MyClass
定义了一个转换运算符 operator int()
。
为了防止这种隐式转换,我们可以使用 explicit
关键字:
#include <iostream>
class MyClass {
public:
explicit operator int() const {
return 42;
}
};
void printInt(int x) {
std::cout << x << std::endl;
}
int main() {
MyClass obj;
// printInt(obj); // Error: no matching function for call to 'printInt(MyClass&)'
printInt(static_cast<int>(obj)); // Correct way to call it
return 0;
}
在这个版本中,printInt(obj)
将导致编译错误,因为 MyClass
的转换运算符被标记为 explicit
,这意味着它不能用于隐式转换。我们必须显式地进行类型转换来调用 printInt
。
总结
explicit
关键字在 C++ 中非常有用,它可以防止意外的隐式转换,从而提高代码的安全性和可读性。它通常用于构造函数和转换运算符,以确保这些函数只能通过显式调用来使用。