7.5.4隐式的类类型转换

转换构造函数的特点

  1. 只接受一个实参的构造函数。

    构造函数只接受一个实参,则它实际上定义了转换为此类类型的隐式转换机制。

  2. 只允许一步类类型转换。

    编译器只会自动的执行一步类型转换。

	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
  1. 类类型转换不是总有效。

    是否需要类型转换依赖于我们对用户使用转换的看法。另外,在类型转换过程中,生成的类类型对象是一个临时量,当函数执行完成时我们就不能再访问它了。

  2. 可以抑制构造函数定义的隐式转换。

    我们可以通过将构造函数声明为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 的。