7.5.4隐式的类类型转换
转换构造函数的特点
-
只接受一个实参的构造函数。
构造函数只接受一个实参,则它实际上定义了转换为此类类型的隐式转换机制。
-
只允许一步类类型转换。
编译器只会自动的执行一步类型转换。
item.combine("9-999-99999-9"); //错误:需要进行两次类型转换
item.combine(string("9-999-99999-9")); //正确:显示转换成string,隐式转换成Sales_data
item.combine(Sales_data("9-999-99999-9")); //正确:显示转换成Sales_data,隐式转换成string
-
类类型转换不是总有效。
是否需要类型转换依赖于我们对用户使用转换的看法。另外,在类型转换过程中,生成的类类型对象是一个临时量,当函数执行完成时我们就不能再访问它了。
-
可以抑制构造函数定义的隐式转换。
我们可以通过将构造函数声明为explicit 加以阻止。
class Sales_data
{
public:
Sales_data() = default;
explicit Sales_data(const std::string &s) : bookNo(s) {}
explicit Sales_data(std::istream);
};
explicit只对一个实参的构造函数有效,但是多个实参的构造函数不能执行隐式类型转换。所以无需将其声明为explicit的。只能在类内声明狗仔函数时使用explicit,在外部定义不应重复。
另外explicit构造韩式只能用于直接初始化
Sales_data item1(null_book); //正确:直接初始化
Sales_data item2 = null_book; //错误:不能用于拷贝初始化
为转换显示使用构造函数
当编译器不能将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 的。