《C++ Primer》中提到:
“可以用单个形参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。”
这里应该注意的是, “可以用单个形参进行调用” 并不是指构造函数只能有一个形参,而是它可以有多个形参,但那些形参都是有默认实参的。
那么,什么是“隐式转换”呢? 上面这句话也说了,是从 构造函数形参类型 到 该类类型 的一个编译器的自动转换。
下面通过代码来看一看:
#include <string>
#include <iostream>
using namespace std;
class BOOK //定义了一个书类
{
private:
string _bookISBN; //书的ISBN号
double _price; //书的价格
public:
//类的构造函数,即那个“能够用一个参数进行调用的构造函数”(虽然它有两个形参,但其中一个有默认实参,只用一个参数也能进行调用)
BOOK(string ISBN, double price = 0.0f) :_bookISBN(ISBN), _price(price) { }
//定义了一个成员函数,这个函数即是那个“期待一个实参为类类型的函数”
//这个函数用于比较两本书的ISBN号是否相同
bool isSameISBN(const BOOK& other)
{
return other._bookISBN == _bookISBN;
}
};
int main()
{
BOOK A("A-A-A");
BOOK B("B-B-B");
cout << A.isSameISBN(B) << endl; //正经地进行比较,无需发生转换
cout << A.isSameISBN(string("A-A-A")) << endl; //此处即发生一个隐式转换:string类型-->BOOK类型,借助BOOK的构造函数进行转换,以满足isSameISBN函数的参数期待。
cout << A.isSameISBN(BOOK("A-A-A")) << endl; //显式创建临时对象,也即是编译器干的事情。
return 0;
}
代码中可以看到,isSameISBN函数是期待一个BOOK类类型形参的,但我们却传递了一个string类型的给它,这不是它想要的啊!还好,BOOK类中有个构造函数,它使用一个string类型实参进行调用,编译器调用了这个构造函数,隐式地将stirng类型转换为BOOK类型(构造了一个BOOK临时对象),再传递给isSameISBN函数。
隐式类类型转换还是会带来风险的,正如上面标记,隐式转换得到类的临时变量,完成操作后就消失了,我们构造了一个完成测试后被丢弃的对象。