explicit是C++中用于修饰类的构造函数的一个关键字,一般用于修饰只有一个参数类的构造函数。
它的作用是防止隐式转换发生,使得只有显式调用才能进行类对象的转换。
当声明了一个使用了explicit关键字的构造函数时,编译器将不再支持隐式转换,需要使用强制类型转换或者显式地调用构造函数来完成转换。
跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)。
主要场景:
- 防止隐式类型转换:如果一个类有多个构造函数,其中一个构造函数可以接收一个参数类型作为输入,而另一个构造函数可以接收该参数类型的引用作为输入,则可以使用explicit关键字来定义这两个构造函数,以防止在不需要的地方发生隐式类型转换。
- 避免二义性:在某些情况下,编译器可能会自动进行类型转换,但是这种类型转换会引起二义性。使用explicit关键字可以避免这种二义性。
- 安全性:使用explicit关键字可以增强代码的安全性,因为它强制开发人员在需要进行类型转换时显式地指定转换方式,而不是依靠编译器的自动转换。
注意事项:
- 只能用于类构造函数,不能用于其他函数。
- explicit关键字只适用于单个参数的构造函数。
- explicit构造函数不能用于隐式转换。
- explicit构造函数可以用于显式转换。
- 如果将explicit关键字应用于默认构造函数,则不能在使用该类时省略括号。
使用示例
- 一个参数的构造函数
class Test { public: explicit Test(int x) { cout << "Constructor called with " << x << endl; } }; int main() { Test obj1(10); // 直接调用构造函数,输出 Constructor called with 10 Test obj2 = 20; // 编译错误,不能使用隐式转换 Test obj3 = Test(30); // 正确,显式调用构造函数 return 0; }
- 一个参数的转换函数
class Test { private: int value; public: explicit Test(int x) : value(x) {} int getValue() const { return value; } }; void func(Test obj) { cout << "The value is " << obj.getValue() << endl; } int main() { func(10); // 编译错误,不能使用隐式转换 func(Test(20)); // 正确,显式调用转换函数 return 0; }
- 非explicit说明
class MyClass { public: MyClass(int num) { ... } }; void doSomething(MyClass obj) { ... } int main() { doSomething(123); // 隐式转换为 MyClass 类型 MyClass obj = 10; // 编译错误,不能隐式调用构造函数 MyClass obj2(10); // 正确 } // 如果 MyClass 构造函数没有使用 explicit 关键字,则上述代码会被编译器自动转换为: doSomething(MyClass(123)); // 显式调用 MyClass 构造函数