彻底搞懂隐式类型转换

《C++ Primer》中提到:

“可以用 单个形参来调用 的构造函数定义了从 形参类型 到 该类类型 的一个隐式转换。”

注意, “可以用单个形参进行调用” 并不是指构造函数只能有一个形参,而是它可以有多个形参,但那些形参都是有默认实参的。

那么,什么是“隐式转换”呢? 从 构造函数形参类型 到 该类类型 的一个编译器的自动转换。

通过下面代码来看一看:

#include <string>
#include <iostream>
using namespace std;
class BOOK  //定义了一个书类
{
private:
	string _bookISBN;  //书的ISBN号
	float _price;      //书的价格

public:
	//定义了一个成员函数,这个函数是“实参为类类型的函数”
	//这个函数用于比较两本书的ISBN号是否相同
	bool isSameISBN(const BOOK & other) {
		return other._bookISBN == _bookISBN;
	}

	//类的构造函数  “传一个参数就可以进行调用的构造函数”(虽然它有两个形参,但其中一个有默认实参,只用一个参数也能进行调用)
	BOOK(string ISBN, float price = 0.0f) :_bookISBN(ISBN), _price(price) {}
};

int main()
{
	BOOK A("A-A-A");   //生命周期是整个main函数
	BOOK B("B-B-B");
	BOOK("C-C-C");    //匿名对象,生命周期在这一行

	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;   //显式创建匿名临时对象,也即是编译器干的事情。

	system("pause");
}

通过代码可以看到,isSameISBN函数需要BOOK类类型的形参,但传递的参数是string类型。但是,BOOK类中有个构造函数,它使用一个string类型实参进行调用,编译器调用了这个构造函数,隐式地将stirng类型转换为BOOK类型(构造了一个BOOK临时对象),再传递给isSameISBN函数。

隐式类类型转换还是会带来风险的,隐式转换得到类的临时变量,完成操作后就消失了,我们构造了一个完成测试后被丢弃的对象。

我们可以通过explicit声明来抑制这种转换:

explicit BOOK(string ISBN,float price=0.0f):_bookISBN(ISBN),_price(price){}

explicit关键字修饰构造函数。会禁止单参构造函数的隐式类型转换。
BOOK类构造函数就不能用于隐式地创造对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值