可接受一个参数的构造函数需用 explicit 关键字限定
5.1.11 ID_missingExplicitConstructor
为了避免意料之外的类型转换,可接受一个参数的构造函数应该用 explicit 关键字限定。
示例:
class String {
public:
String(int capacity); // Non-compliant, missing ‘explicit’
....
};
void foo(const String&);
int bar() {
foo(100); // Can be compiled, but very odd
}
由于 String 类的构造函数接受一个 int 型参数,foo(100) 相当于将 100 隐式转为 String 类的对象,这种隐式转换是怪异的,也往往意味着意料之外的错误。
应改为:
class String {
public:
explicit String(int capacity); // Compliant
....
};
这样 foo(100) 这种写法便不会通过编译。
例外:
class String {
public:
String(const String&); // Explicit or not depends on your design intent
String(String&&); // ditto
....
};
拷贝、移动构造函数可不受本规则约束,如果将拷贝、移动构造函数声明为 explicit 则无法再按值传递参数或按值返回对象。在类的接口设计中,应尽量减少隐式转换以避免不易察觉的问题。
相关
参考
C++ Core Guidelines C.46
MISRA C++ 2008 12-1-3