C++显式声明explicit

打印 上一主题 下一主题

主题 1747|帖子 1747|积分 5241

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
C++显示声明explicit

在 C++ 中,explicit 关键字用于修饰单参数构造函数多参数构造函数(C++11 起),其核心作用是禁止编译器的隐式类型转换

一、必须加 explicit 的典型场景

1. 单参数构造函数

当构造函数只有一个参数时,编译器会尝试自动执行隐式类型转换,大概导致不测行为。
示例(未加 explicit 的隐患):
  1. class String {
  2. public:
  3.     String(int size) { // 允许隐式转换:int → String
  4.         // 构造一个长度为 size 的字符串
  5.     }
  6. };
  7. void printString(const String& s) { /* ... */ }
  8. int main() {
  9.     printString(10); // 隐式转换:int 10 → String 对象
  10.     // 程序员可能误以为参数是字符串内容,而非长度
  11. }
复制代码
修复方法:
  1. explicit String(int size) { /* ... */ } // 禁止隐式转换
复制代码
此时 printString(10) 会编译报错,必须显式调用:
  1. printString(String(10)); // 明确意图:构造一个长度为10的字符串
复制代码

2. 多参数构造函数(C++11 起)

C++11 支持多参数的隐式转换(通过统一初始化语法 {}),需用 explicit 禁止。
示例:
  1. class Vec3 {
  2. public:
  3.     Vec3(int x, int y, int z) { /* ... */ }
  4. };
  5. void moveRobot(const Vec3& direction) { /* ... */ }
  6. int main() {
  7.     moveRobot({1, 2, 3}); // 隐式构造 Vec3 对象(可能意外)
  8. }
复制代码
修复方法:
  1. explicit Vec3(int x, int y, int z) { /* ... */ }
复制代码
此时必须显式创建对象:
  1. moveRobot(Vec3{1, 2, 3}); // 明确传递 Vec3 类型
复制代码

二、发起加 explicit 的场景

1. 避免歧义的构造函数

若一个类有多个构造函数,且参数类型大概引发歧义:
  1. class File {
  2. public:
  3.     explicit File(const std::string& path) { /* 通过路径打开文件 */ }
  4.     explicit File(int fd) { /* 通过文件描述符打开文件 */ }
  5. };
复制代码
若无 explicit,File f = "data.txt"; 或 File f = 123; 会导致隐式构造,大概隐藏逻辑错误。

2. 容器或资源管理类

比方智能指针、容器类,隐式转换大概导致资源管理混乱:
  1. class UniquePtr {
  2. public:
  3.     explicit UniquePtr(T* ptr) { /* 接管资源 */ }
  4. };
复制代码
防止不测构造:UniquePtr<int> p = new int(42);(错误,必须显式构造)。

三、不必要加 explicit 的场景

1. 明白的转换构造函数

若故意允许隐式转换(如 std::string 允许从 const char* 转换):
  1. class MyString {
  2. public:
  3.     MyString(const char* str) { /* ... */ } // 允许隐式转换
  4. };
复制代码

2. 拷贝/移动构造函数

通常不必要,由于拷贝/移动是明白的语义:
  1. class Widget {
  2. public:
  3.     Widget(const Widget&) = default;    // 拷贝构造
  4.     Widget(Widget&&) = default;         // 移动构造
  5. };
复制代码

四、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企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表