自动类型转换

内容简介

C++ 中单参数构造函数和类型转换运算符可能触发隐式类型转换。它能让接口更方便,也可能让代码产生意外匹配。explicit 用于禁止不希望发生的隐式转换。

用法

构造函数触发转换

class Number {
public:
    Number(int value) : value_(value) {}
 
private:
    int value_ = 0;
};
 
Number n = 10;  // int 隐式转换为 Number

explicit 禁止隐式转换

class Number {
public:
    explicit Number(int value) : value_(value) {}
 
private:
    int value_ = 0;
};
 
Number a(10);          // 正确
Number b = Number(10); // 正确
// Number c = 10;      // 错误

类型转换运算符

class Number {
public:
    explicit operator int() const
    {
        return value_;
    }
 
private:
    int value_ = 10;
};

最佳代码实践

  • 单参数构造函数默认考虑加 explicit
  • 只有当隐式转换非常自然、无损且符合直觉时,才允许它发生。
  • 类型转换运算符要谨慎使用,容易造成重载解析混乱。
  • C++ 强制转换优先使用 static_castdynamic_castconst_castreinterpret_cast,不要滥用 C 风格强转。

错误用法

class File {
public:
    File(const char* path);
};
 
void open(File file);
 
open("data.txt");  // 可能意外构造 File,建议构造函数加 explicit
class A {
public:
    A(int);
    A(double);
};
 
A a = 1.2f;  // 可能出现不清晰的重载选择

注意事项

  • std::string s = "abc"; 是常见且合理的隐式转换。
  • explicit 不禁止显式构造,例如 Number n(10)
  • C++20 支持条件 explicit,初学阶段先掌握普通 explicit 即可。

相关:CandCpp数据变量进阶cpp函数进阶

学习路径