类的自动转换
可以将类定义成与基本类型或另一个类相关,使得从一种类型转换为另一种类型是有意义的。我们可以指示c++如何自动转换或者通过强制转换来完成。自动转换实际是通过只接受一个参数的构造函数来实现的。如果构造函数有两个参数,只要其中一个参数提供了默认值,那么它也可用于转换。
class Stonewt
{
enum {Lbs_per_stn = 14};
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
Stonewt(int stn, double lbs);;
Stonewt();
~Stonewt();
};
Stonewt::Stonewt(double lbs)
{
stone = int (lbs) / Lbs_per_stn;
pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
}
int main()
{
Stonewt myCat;
myCat = 19.96;//通过构造函数会将double 19.6转换为Stonewt 对象,它是隐式的。
}
C++新增了关键字explicit,用于关闭这种自动特性,用在函数声明时。使用之后只能进行如下的显示转换,
explicit Stonewt(double lbs);
myCat = Stonewt (19.96);
myCat = (Stonewt) 19.96;
否则还可以用于下面的隐式转换:
• 将对象Stonewt 初始化为double值时;
• 将double值赋给Stonewt 对象时;
• 将double值传递给接受Stonewt 参数的函数时;
• 返回值被声明为Stonewt 的函数试图返回double值时;
如果传入的参数不是double,是一个int,它会先将int转换为double,然后再转换成类。
转换函数
那么可以将Stonewt类转换为double吗?
构造函数只用于从某种类型到类类型的转换,要进行相反的转换,必须使用特殊的C++运算函数——转换函数。它时用户定义的强制类型转换。例如:
Stonewt wolfe(999.9);
double host = double (wolfe);
double thinker = (double) wolfe;
//或者让编译器来决定
Stonewt wells(30, 4);
double star = wells;
如果编译器发现,右侧是Stonewt 类型,左侧是double类型,因此它将查看程序员是否定义了与此匹配的转换函数。
创建转换函数的方法:
operator typyeName();
需要注意的是:
• 转换函数必须是类的方法;
• 转换函数不能指定返回类型;虽然没有声明返回类型,但这两个函数也将返回所需的值。
• 转换函数不能有参数。
当类定义了两种或更多的转换时,推荐使用显式强制类型转换来避免二义性。
在C++98中,关键字explicit不能用于转换函数,但C++11消除了这种限制
explicit operator int() const;
有了explicit声明后,需要强制转换时只能显式调用这些运算符。