11.6

11.6 类的自动转化和强制类型转换

类对象直接赋值将会调用匹配的构造函数
Stone myCat;
myCat = 19.6; // 相当于
myCat = Stonewt (19.6); // 隐式转换
只有接受一个参数的构造函数才能作为转换函数。
如果给其他参数提供默认值, 也可以。
关键字:explicit, 关闭这种特性
explicit Stonewt (double lbx);
关闭隐式转换, 但是可以显式转换
myCat = 19.6; // not valid
myCat = Stonewt(19.6);
myCat = (Stonewt) 19.6;

什么时候进行隐式转换

P413
如果转换存在二义性, 就不会进行转换。
比如存在:
Stonewt(long);
Stonewt(double);
当将int值赋给Stonewt对象时, 不会进行转换, 因为int可以被转换位long, 也可以被转换为double

转换函数

如果double可以被转换位Stonewt, 那么Stonewt是否可以被转换为double?
转换函数是用户定义的强制类型转换, 可以像使用强制类型转换那样使用他们。
Stonewt wolfe(285.7);
double host = double (wolfe);
double host = (double) wolfe;
double star = wells;
转换函数的形式:
operator typeName();
转换函数必须是类函数
转换函数不能指定返回类型
转换函数不能有参数

原型

operator double();
将原型放入类声明中
double指出了转换后的类型, 所以不需要返回值
类方法由类对象调用, 所以不需要参数

定义

虽然没有声明返回值类型, 但是函数也要返回所需的值。
Stonewt::operator double() const
{
return pounds;
}
注意转换时可能会出现二义性:
如果有多个转换函数, 应当显式地指出转换的类型, 否则编译器可能不知道要转换位哪一种类型。
缺点
用户不希望进行转换时, 转换函数也可能进行转换。
1.在C++98中, explicit不能用于转换函数, C++11解除了这种限制。
添加explict关键字, 将只能强制类型转换。
2.用其他的函数替换转换函数。
int Stonewt::Stone_to_Int() { return int (pounds + 0.5); }
最好不要依赖于这种隐式转换函数

转换函数和友元函数

过多的转换会导致二义性