☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

可接受一个参数的构造函数需用 explicit 关键字限定

5.1.11 ID_missingExplicitConstructor
目录 › next › previous

为了避免意料之外的类型转换,可接受一个参数的构造函数应该用 explicit 关键字限定。

示例:

class String {
public:
    String(int capacity);   // Non-compliant, missing ‘explicit’
    ....
};

例中 String 是一个字符串类,String(int) 用于设定字符串对象的初始容量,但下列代码可以通过编译:

String foo = 100;   // Odd, the string is "100"?

void bar(const String&);

void baz() {
    bar(100);   // Unexpected implicit conversion
}

由于 String 类的构造函数接受一个 int 型参数,例中整数 100 可以被隐式转换为 String 类的对象,这种转换易造成意料之外的错误或开销。

应使用 explicit 关键字限定可接受一个参数的构造函数:

class String {
public:
    explicit String(int capacity);   // Compliant
    ....
};

这样从 int 到 String 的隐式转换会被禁止。在接口设计中,应尽量减少隐式转换以避免意料之外的问题。

例外:

class String {
public:
    String(const String&);   // Compliant
    String(String&&);        // Compliant
    ....
};

拷贝、移动构造函数可不受本规则约束,如果拷贝、移动构造函数被 explicit 关键字限定则无法再按值传递参数或按值返回对象。

另外,为了提高易用性,在类是构造函数参数的扩展、视图等情况下,可以不使用 explicit 关键字,但相关设计需要通过评审,本规则不放宽对这种情况的要求,如:

class String {
public:
    String(const char*);   // Non-compliant, manual review is required
    ....
};

class StringView {
public:
    StringView(const String&);   // Non-compliant, ditto
    ....
};

String s = "a";     // Easy to understand
StringView v = s;   // Ditto

例中字符串字面常量转为字符串类对象、字符串对象转为字符串视图是易于理解的,但可能不便于审计工具进行量化分析,需要人工评审。

相关

ID_missingExplicitConvertor

参考

C++ Core Guidelines C.46 MISRA C++ 2008 12-1-3
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.