❝C 的explicit关键词一般用来构造函数中,让其不能隐式转换。❞
比如有类String
代码语言:javascript复制struct String
{
String(int size)
{
}
};
使用类String我们很自然地会写成这样。
代码语言:javascript复制String str = 1;
// 隐式转换,相当于String str = String(1);
但如果使用了explicit修饰构造函数则会导致报错。
代码语言:javascript复制struct String
{
explicit String(int size)
{
}
};
// String str = 1; // 编译错误
上面介绍了explicit的使用,大概意思就是限制用户的某一行为。实际上加不加explicit都差不多呀,不加更方便呢。
默认的隐式转换可以说是编译器的一个特性,虽然会让工程师方便地写代码,但同时也会有副作用。比如:
代码语言:javascript复制struct String
{
String(int size)
{
}
};
void print(const String &str)
{
}
print(3); // 预想打印数字3,却是输出长度为3的空字符串。
虽然不使用explicit关键词可以方便地写少代码,但在某种情况下会导致意想不到的问题。而使用explicit关键词则可以增强代码健壮性,但需要额外多写代码。
什么时候使用explicit呢?
Qt君认为,一般用在构造函数存在单个参数时就需要explicit修饰。
引申
构造函数的多个参数在某些情况下依然需要explicit,但一般情况下不需要添加,因为多个参数的构造函数,在写法上已经会让人去了解到可能存在的问题。比如:
代码语言:javascript复制struct String
{
String(int size, int maxSize)
{
}
};
void print(const String &str)
{
}
print({1, 5});
上面的列表初始化就已经会让人看到这是一个字符串的初始化,和先前的print(3)明显区分了。
此外我们还可以使用explicit修饰重载类型符,比如:
代码语言:javascript复制struct A
{
explicit A(int n)
{
}
explicit operator bool() const
{
return true;
}
};
A a(1);
bool b = a; // 编译错误,不能隐式转换。
关于更多
更为详细的explicit关键词介绍。https://en.cppreference.com/w/cpp/keyword/explicit