

新闻资讯
技术学院explicit关键字用于禁止单参数构造函数的隐式类型转换,提升安全性与可读性;如String s = 10或print(42)将报错,必须显式调用String(10)或print(String(42))。
explicit 关键字用于修饰单参数构造函数(或多个参数但除第一个外都有默认值的构造函数),它的核心作用是禁止编译器进行隐式类型转换,从而避免意外的、不易察觉的类型转换行为,提升代码的安全性和可读性。
没有 explicit 时,编译器可能在你不注意的地方自动调用构造函数完成类型转换。比如:
class String {
public:
String(int n) { /* 分配 n 字节内存 */ }
String(const char* s) { /* 构造字符串 */ }
};此时下面的代码能悄悄通过:
String s = 10; // 隐式调用 String(int),s 变成一个长度为 10 的空字符串 void print(String str); print(42); // 隐式转换:传入 int 42 → 构造临时 String 对象 → 调用 print
这通常不是程序员本意,容易引发逻辑错误或性能问题(如无意义的临时对象)。
加上 explicit 后:
class String {
public:
explicit String(int n) { /* ... */ }
explicit String(const char* s) { /* ... */ }
};String s = 10; → 编译错误
String s(10); → 正确:直接初始化String s{10}; → 正确:列表初始化(C++11 起 explicit 也禁止隐式列表转换)pri
nt(42); → 编译错误;必须写成 print(String(42)) 或 print(String{42})
std::unique_ptr(int) 不合法,但自定义句柄类常有类似需求)Duration(int ms))、字符串转解析类(如 Json(const char*))等String s(10) 或 String s{10},只禁用 = 形式的隐式转换看似方便,实则埋雷:
func(5) 竟然能编译通过explicit 是一种“防御性编程”习惯——宁可多敲几个字符,也不留模糊空间。现代 C++ 项目中,除非明确需要隐式转换(极少见),否则单参数构造函数应默认加上 explicit。