Backto C/C++ Index
The keyword
explicit
is used to prevent implicit conversion.关键字
explicit
是用来阻止不合时宜的隐式类型转换的.
隐式转换 : 可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。
例如我们这里有一个类, things,
class things
{
public:
things(const std::string&name =""):
m_name(name),height(0),weight(10){}
int CompareTo(const things & other);
std::string m_name;
int height;
int weight;
};
应为这里 things 的构造函数只用了一个实参完成初始化, 所以这里可以进行一个隐式转换.
things a;
................//在这里被初始化并使用。
std::string nm ="book_1";
//由于可以隐式转换,所以可以下面这样使用
int result = a.CompareTo(nm);
这段程序使用一个string类型对象作为实参传给things的CompareTo函数。这个函数本来是需要一个tings对象作为实参。现在编译器使用string nm来构造并初始化一个things对象,新生成的临时的things对象被传递给CompareTo函数,并在离开这段函数后被析构。
但是这种自动的隐式转换, 可能造成未知的麻烦, 比如在上面的构造函数中同时也初始化了 weight =0
, 如果这个数在 CompareTo 中做了被除数, 那就有问题了, 那么我们就需要构造之后手动给 weight 赋值. 所以我们使用 explicit
来禁止掉这种自动的隐式转换.
规范代码写成这样
class things
{
public:
explicit things(const std::string&name =""):
m_name(name),height(0),weight(0){}
int CompareTo(const things & other);
std::string m_name;
int height;
int weight;
};
这时候,
int result = a.CompareTo(nm); // 报错
int result = a.CompareTo(things(nm)); // OK, 显式调用构造函数
在 Google C++ style guide 中, 明确规定, 所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明为explicit,例如作为其他类的透明包装器的类。
Ref
- C++中explicit关键字的作用 : 转自这篇文章