在 C++ 中,explicit
关键字用于防止隐式的单参数构造函数调用,从而避免意外的类型转换。它通常用于类的构造函数声明中,确保只有显式的构造函数调用才会创建类的对象。
作用
-
防止隐式转换:
- 如果构造函数没有被声明为
explicit
,编译器会允许隐式的类型转换,这可能导致意外的行为。 - 使用
explicit
可以避免这种隐式转换,提高代码的安全性和可读性。
- 如果构造函数没有被声明为
-
控制构造函数的调用方式:
explicit
构造函数只能通过显式的调用方式来创建对象。- 非
explicit
构造函数可以通过隐式转换来创建对象。
示例
#include <iostream>
class MyClass {
public:
// 非 explicit 构造函数
MyClass(int value) : data(value) {}
void print() const {
std::cout << "data: " << data << std::endl;
}
private:
int data;
};
class YourClass {
public:
// explicit 构造函数
explicit YourClass(int value) : data(value) {}
void print() const {
std::cout << "data: " << data << std::endl;
}
private:
int data;
};
int main() {
// 对于 MyClass,允许隐式转换
MyClass obj1 = 10; // 隐式调用构造函数
obj1.print();
MyClass obj2(20); // 显式调用构造函数
obj2.print();
// 对于 YourClass,不允许隐式转换
// YourClass obj3 = 30; // 错误:隐式转换被禁止
YourClass obj4(30); // 显式调用构造函数
obj4.print();
return 0;
}
输出
data: 10
data: 20
data: 30
解释
MyClass
的构造函数没有被声明为explicit
,因此允许隐式转换。可以直接用int
类型的值初始化MyClass
对象。YourClass
的构造函数被声明为explicit
,因此不允许隐式转换。必须显式地调用构造函数来创建对象。
适用场景
-
避免意外的类型转换:
- 当构造函数可能被隐式调用时,使用
explicit
可以避免意外的行为。 - 例如,防止将一个整数隐式转换为类的对象。
- 当构造函数可能被隐式调用时,使用
-
提高代码的可读性和安全性:
- 显式的构造函数调用使代码更加清晰,避免隐式转换带来的潜在问题。
-
单参数构造函数:
- 特别适用于只有一个参数的构造函数,因为这些构造函数最容易被隐式调用。
总结
explicit
关键字用于防止隐式的单参数构造函数调用,确保只有显式的构造函数调用才会创建类的对象。这有助于提高代码的安全性和可读性,避免意外的类型转换。