类的自动转换与强制类型转换
类的自动转换就是说,可以将类定义成与基本类型或另一个类相关,使得从一种类型转换为另一种类型是相关的
以下定义一个将磅转换为英石(磅和英石是重量单位)的一个类,1英石(st) = 14磅(lb)
class Stonewt
{
private:
enum {Lbs_per_stn = 14}; // 每磅14英石
int stone; // 整数部分英石
double pds_left; // 除去整数英石,剩下的小数部分多少磅
double pounds; // 多少磅
public:
Stonewt(double lbs); // 带一个doule参数的构造函数
Stonewt(int stn, double lbs); // 带一个doule参数和一个int参数的构造函数
Stonewt(); // 默认构造函数
~Stonewt(); // 析构函数
void show_lbs() const; // 显示一共有多少磅
void show_stn() const; // 显示一共有多少英石
};
各个函数的定义如下:
// 带一个doule参数的构造函数
Stonewt::Stonewt(double lbs)
{
stone = int (lbs) / Lbs_per_stn;
pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
}
// 带一个doule参数和一个int参数的构造函数(int stone代表英石整数部分,double lbs代表英石小数部分)
Stonewt::Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn +lbs;
}
// 默认构造函数
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
}
// 析构函数
Stonewt::~Stonewt()
{
}
// 显示一共有多少磅
void Stonewt::show_lbs() const
{
cout << pounds << " pounds\n";
}
// 显示一共有多少英石
void Stonewt::show_stn() const
{
cout << stone << " stone, " << pds_left << " pounds\n";
}
C++提供了可以通过接受一个参数的构造函数,把这个参数类型的数值转换为类,而且是将这个参数类型,自动转换为类,而且是一种隐式转换,代码如下
Stonewt mycat;
mycat = 19.6;
在C++中,这两句话将通过构造函数Stonewt(double lbs)自动创建一个临时对象,然后将19.6传入,随后就把这个临时对象中的数据逐个赋值给mycat,这都是自动完成的.
只有接受一个参数的构造函数才可以完成这个自动转换的操作,像这样Stonewt(int stn, double lbs)带两个构造函数的参数就不行,如果Stonewt(int stn, double lbs = 0)是这样的,带了一个默认值,相当于只有一个参数的构造函数,就可以完成自动转换工作,转换为int型
注意,为了不发生意外的类型转换,我们可以使用explicit这个关键字加载类中的成员函数声名中来使用禁用这种隐式转换,只能用显示的转换,比如
explicit Stonewt(double lbs);
这样,就会报错
Stonewt mycat;
mycat = 19.6;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FZ6VcQ3p-1590352330993)(QQ截图20191119210251.jpg)]
只能这样操作才能进行强制转换,如果在声名中使用了关键字explicit,则Stonewt(19.6)将只用于强制转换类型.
mycat = Stonewt(19.6);
mycat = (Stonewt)19.6;
转换函数
以上是某种类型往类这种类型转换的实例,但是要从类转换为某种类型,这个时候就出现了转换函数.如果定义了从Stonewt到double的转换函数,就可以直接使用以下操作
Stonewt wolfe(285.7);
double host = double(wolfe);
double thinker = (double)wolfe;
转换函数的声名如下,抽象的可以表示为operator typeName();
operator double();
operator int();
转换函数不能有返回值,不能有参数,必须是类方法,只能在函数中return某个参数.
重新定义一个类加入了转换函数
class Stonewt
{
private:
enum {Lbs_per_stn = 14}; // 每磅14英石
int stone; // 整数部分英石
double pds_left; // 除去整数英石,剩下的小数部分多少磅
double pounds; // 多少磅
public:
Stonewt(double lbs); // 带一个doule参数的构造函数
Stonewt(int stn, double lbs); // 带一个doule参数和一个int参数的构造函数
Stonewt(); // 默认构造函数
~Stonewt(); // 析构函数
void show_lbs() const; // 显示一共有多少磅
void show_stn() const; // 显示一共有多少英石
operator int() const;
operator double() const;
};
这两个转换函数定义如下
Stonewt::operator int() const
{
return int (pounds + 0.5); //采用四舍五入的规则,int(element)只会保留整数部分,所以加上0.5
}
Stonewt::operator double()const
{
return pounds;
}