explicit与隐式类型转换

1、普通类型通过隐式转换为类类型:
类声明中只接受一个参数的构造函数,或接受多个参数但其余参数均有默认值时可以进行隐式类型转换,例子:

// .h
Class Stone{
private:
	double abc;
public:
	Stone() {}
	Stone(double para1){abc = para1;}
	Stone_show(){cout<<abc;}
};

//.cpp
Stone s1;
s1 = 15.2; //首先调用Stone(double)生成临时对象,然后利用默认赋值运算符对s1进行赋值,这一过程称为隐式转换。

隐式转换可能不是程序想要的,为避免隐式转换的发生,C++提供了explicit关键字,如下:

//.h
Class Stone{
...
	explicit Stone(double para1){abc = para1;}
...
};

//.cpp
Stone s1 = 15.2; //报错
Stone s1 = Stone(15.2); //显式转换可以
Stone s1 = (Stone)15.2; //显式转换可以

若在声明中构造函数使用了explicit,则Stone(double)只能用于显式类型转换,未使用explicit,则在一下几种情况会进行隐式类型转换:
1、将Stone对象初始化为double值;
2、将double值赋给Stone对象时;
3、将double值作为参数传给Stone对象作参数的函数时;
4、函数返回值为Stone,但将double值返回时;
5、上述情况中,使用可转为double的其他内置类型时,如int。

//.cpp
void show(const Stone& a){
	a.Stone_show();
}
Stone s1 = 20; // int先转为double,然后调用隐式转换。
show(20); // 20先转为double,然后隐式转换,变成show()函数要求的Stone类型

2、类对象通过定义的转换函数转换为普通类型:
即为实现如下转换:

Stone s1(20.1);
double db1 = s1; //此过程需要通过C++运算符函数——转换函数进行

转换函数operator typename();需求:
1、转换函数必须是类方法;
2、转换函数不能指定返回类型;
3、转换函数不能有参数。

//.h
Class Stone{
...
	operator double () const {return abc}
};

//.cpp
Stone s1;
double res = double(s1); //显式转换
double res = (double)s1; //显式转换
double res = s1; //隐式转换

a) 转换函数中typename指出了要转换的类型,因此不需要指定返回类型;因为是类方法,需要类对象调用,因此函数不需要参数
b) 也可通过将该转换函数声明为explicit禁止隐式转换。
c) 当定义了两个转换函数时,如转为int和double两个,调用隐式转换时存在二义性,编译失败,但显式转换依然可以。

参考资料:C++ Primer Plus 11.6节

总结:

1、当类的构造函数只接受一个参数且未声明为explicit时可进行隐式转换,将参数类型转换为类类型,在将与类中构造函数参数类型相同的值赋给对象时,自动调用。
2、通过自定义转换函数operator typename();,可将类类型转换为其他指定类型,也可通过explicit关键字禁止隐式转换,将类对象赋值给typename变量时,自动调用。
3、经验表明,最好不要依赖隐式转换。
4、隐式类型转换只针对函数中调用参数,调用者不能转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值