马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
C++显示声明explicit
在 C++ 中,explicit 关键字用于修饰单参数构造函数或多参数构造函数(C++11 起),其核心作用是禁止编译器的隐式类型转换。
一、必须加 explicit 的典型场景
1. 单参数构造函数
当构造函数只有一个参数时,编译器会尝试自动执行隐式类型转换,大概导致不测行为。
示例(未加 explicit 的隐患):
- class String {
- public:
- String(int size) { // 允许隐式转换:int → String
- // 构造一个长度为 size 的字符串
- }
- };
- void printString(const String& s) { /* ... */ }
- int main() {
- printString(10); // 隐式转换:int 10 → String 对象
- // 程序员可能误以为参数是字符串内容,而非长度
- }
复制代码 修复方法:
- explicit String(int size) { /* ... */ } // 禁止隐式转换
复制代码 此时 printString(10) 会编译报错,必须显式调用:
- printString(String(10)); // 明确意图:构造一个长度为10的字符串
复制代码 2. 多参数构造函数(C++11 起)
C++11 支持多参数的隐式转换(通过统一初始化语法 {}),需用 explicit 禁止。
示例:
- class Vec3 {
- public:
- Vec3(int x, int y, int z) { /* ... */ }
- };
- void moveRobot(const Vec3& direction) { /* ... */ }
- int main() {
- moveRobot({1, 2, 3}); // 隐式构造 Vec3 对象(可能意外)
- }
复制代码 修复方法:
- explicit Vec3(int x, int y, int z) { /* ... */ }
复制代码 此时必须显式创建对象:
- moveRobot(Vec3{1, 2, 3}); // 明确传递 Vec3 类型
复制代码 二、发起加 explicit 的场景
1. 避免歧义的构造函数
若一个类有多个构造函数,且参数类型大概引发歧义:
- class File {
- public:
- explicit File(const std::string& path) { /* 通过路径打开文件 */ }
- explicit File(int fd) { /* 通过文件描述符打开文件 */ }
- };
复制代码 若无 explicit,File f = "data.txt"; 或 File f = 123; 会导致隐式构造,大概隐藏逻辑错误。
2. 容器或资源管理类
比方智能指针、容器类,隐式转换大概导致资源管理混乱:
- class UniquePtr {
- public:
- explicit UniquePtr(T* ptr) { /* 接管资源 */ }
- };
复制代码 防止不测构造:UniquePtr<int> p = new int(42);(错误,必须显式构造)。
三、不必要加 explicit 的场景
1. 明白的转换构造函数
若故意允许隐式转换(如 std::string 允许从 const char* 转换):
- class MyString {
- public:
- MyString(const char* str) { /* ... */ } // 允许隐式转换
- };
复制代码 2. 拷贝/移动构造函数
通常不必要,由于拷贝/移动是明白的语义:
- class Widget {
- public:
- Widget(const Widget&) = default; // 拷贝构造
- Widget(Widget&&) = default; // 移动构造
- };
复制代码 四、explicit 的影响对比表
场景无 explicit有 explicit单参数构造允许隐式类型转换(如 T obj = 66;)必须显式构造(如 T obj(66);)多参数构造(C++11)允许 T obj = {a, b};必须 T obj{a, b}; 或 T obj(a, b);函数传参允许隐式转换参数必须显式通报对象 五、最佳实践
- 默认优先加 explicit:除非明白必要隐式转换,否则为所有单参数/多参数构造函数添加 explicit。
- 代码安全性:避免因隐式转换导致的逻辑错误(如 std::vector<int> v = 10; 实际构造的是包罗10个元素的向量,而非包罗元素10的向量)。
- 进步可读性:欺压显式构造,使代码意图更清晰。
通过合理使用 explicit,可以明显提升代码的结实性和可维护性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |