explicit : 明确的,显示的
抑制构造函数定义的隐式转换
将构造函数声明为explicit加以阻止
class sales_data{
public:
sales_data() = default;
sales_data(const string&s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
explict sales_data(const string&s):bookNo(s){}
explict sales_data(istream&);
}
没有任何构造函数用于隐式地创建sales_data对象,两种用法都无法通过编译:
item.combine(null_book);//错误:string构造函数是explicit
item.combine(cin);//错误:istream构造函数是explicit
- 关键字explicit只对一个实参的构造函数有效
- 需要多个实参的构造函数不能用于执行隐式转换,所以无需将这些构造函数指定为explicit的
- 只能在类内声明构造函数时使用explicit关键字,在类外部定义时不应重复
explicit构造函数只能用于直接初始化
发生隐式转换的一种情况:当我们执行拷贝形式的初始化时(使用=),此时,我们只能使用直接初始化而不能使用explicit构造函数:
sales_data item1(null_book);//正确:直接初始化
sales_data item2 = null_book;//错误:不能将explicit构造函数用于拷贝形式的初始化过程
NOTE:当我们使用explicit关键字声明构造函数时,它将只能以直接初始化的形式来使用。
为转换显示地使用构造函数
强制类型转换
item.combine(sales_data(null_book));//正确:显示构造sales_data对象
item.combine(static_cast<sales_Data>(cin));//正确:static_cast执行显示类型转换
标准库中含有显示(explicit)构造函数的类
我们用过一些标准库中的类含有但参数的构造函数:
- 接受一个单参数的const char* 的string构造函数不是explicit的
- 接受一个容量参数的vector构造函数是explicit