在 C++ 中,explicit
是一个用于修饰构造函数的关键字,它主要用于防止隐式类型转换,下面从多个方面详细介绍它。
基本语法
explicit
关键字只能用于修饰类的构造函数,其语法形式如下:
class ClassName {
public:// 带有 explicit 修饰的构造函数explicit ClassName(parameter_list);
};
隐式类型转换问题
在没有 explicit
关键字时,单参数的构造函数(或者除了第一个参数外其余参数都有默认值的构造函数)可以用于隐式类型转换。以下是一个示例:
#include <iostream>
class MyClass {
public:// 单参数构造函数MyClass(int num) : value(num) {std::cout << "Constructor called with value: " << num << std::endl;}void printValue() {std::cout << "Value: " << value << std::endl;}
private:int value;
};void func(MyClass obj) {obj.printValue();
}int main() {// 隐式类型转换func(10); return 0;
}
在上述代码中,func(10)
会触发隐式类型转换,将整数 10
转换为 MyClass
类型的对象,因为 MyClass
的单参数构造函数允许这种转换。
使用 explicit 防止隐式类型转换
当使用 explicit
修饰构造函数时,会禁止这种隐式类型转换,只能进行显式类型转换。示例如下:
#include <iostream>
class MyClass {
public:// 使用 explicit 修饰构造函数explicit MyClass(int num) : value(num) {std::cout << "Constructor called with value: " << num << std::endl;}void printValue() {std::cout << "Value: " << value << std::endl;}
private:int value;
};void func(MyClass obj) {obj.printValue();
}int main() {// 显式类型转换func(MyClass(10)); // 以下代码会编译错误,因为禁止了隐式类型转换// func(10); return 0;
}
在这个例子中,explicit
关键字阻止了 func(10)
这样的隐式类型转换,必须使用 func(MyClass(10))
进行显式类型转换。
多参数构造函数与 explicit
explicit
也可以用于除了第一个参数外其余参数都有默认值的多参数构造函数,防止隐式类型转换。示例如下:
#include <iostream>
class Rectangle {
public:// 多参数构造函数,除第一个参数外其余有默认值explicit Rectangle(int width, int height = 10) : w(width), h(height) {std::cout << "Rectangle created with width: " << w << ", height: " << h << std::endl;}void printArea() {std::cout << "Area: " << w * h << std::endl;}
private:int w;int h;
};void printRectArea(Rectangle rect) {rect.printArea();
}int main() {// 显式类型转换printRectArea(Rectangle(5)); // 以下代码会编译错误,禁止隐式类型转换// printRectArea(5); return 0;
}
总结
explicit
关键字的主要作用是避免意外的隐式类型转换,提高代码的安全性和可读性。当你不希望构造函数被用于隐式类型转换时,应该使用 explicit
修饰构造函数。