1.自动转换
C++程序员可以指示C++如何自动进行转换,或通过强制类型转换来完成。在C++中,接受一个参数的构造函数为将类型与该参数相同的值转换为类提供了可能。
我们举一个例子来说明:以两种方式(磅和英石)来表示重量。
程序示例:
stonewt1.h
构造函数:
程序将使用构造函数Stonewt(double)来创建一个临时的Stonewt对象,并将19.6作为初始值。随后,采用逐成员赋值的方式将该临时对象的内容复制到myCat中。
这一过程称为隐式转换,因为它是自动进行的,而不需要显示强制类型转换。不过这种自动转换并非总是合乎需求的,因此,可以使用一个关键字(explicit)来关闭这种自动特性。即可以这样声明构造函数:
2.转换函数(强制类型转换)
上述程序将数字转换为Stonewt对象,其实也可将Stonewt对象转换为double值,但不是使用构造函数,必须使用特殊的C++操作符函数--转换函数。
转换函数的格式:
typeName(这里为double)指出了要转换成的类型,因此不需要指定返回类型,转换函数是类方法意味着:它需要通过类对象来调用,从而告知函数要转换的值。因此,函数不需要参数。
注意:
转换函数必须是类方法。
转换函数不能指定返回类型。
转换函数不能有参数。
总结:
C++为类提供了下面的类型转换:
1.只有一个参数的类构造函数用于将类型与该参数相同的值转换为类类型。例如,将double值赋给Stonewt对象时,接受int参数的Stonewt类构造函数将自动被调用。不过,在构造函数声明中使用explicit可防止隐式转换,而只允许显示转换。
2.被称为转换函数的特殊类成员操作符函数,用于将类对象转换为其他类型。转换函数是类成员,没有返回类型、没有参数、名为operator typeName(),其中,typeName是对象将被转换成的类型。将类对象赋给typeName变量或将其强制转换为typeName类型时,该转换函数将被调用。
C++语言不自动转换不兼容的类型,例如,下面的语句:
<span style="white-space:pre"> </span>int *p = 10;
是非法的,因为左边是指针类型,而右边是数字。不过在无法自动转换时,可以使用强制类型转换:
<span style="white-space:pre"> </span>int *p = (int *)10;
上述语句将10强制转换为int指针类型,将指针设置为地址10.
C++程序员可以指示C++如何自动进行转换,或通过强制类型转换来完成。在C++中,接受一个参数的构造函数为将类型与该参数相同的值转换为类提供了可能。
我们举一个例子来说明:以两种方式(磅和英石)来表示重量。
程序示例:
stonewt1.h
<pre name="code" class="cpp">//stonewt1.h--revised definition for Stonewt class
#ifndef STONEWT1_H_
#define STONEWT1_H_
class Stonewt
{
private:
enum{lbs_pr_stn = 14};
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
Stonewt(int stn,double lbs);
Stonewt();
~Stonewt();
void show_lbs()const;
void show_stn()const;
//conversion functions
operator int()const;
operator double()const;
};
#endif
</pre><span style="white-space:pre"> </span>stonewt1.cpp</p><p><pre name="code" class="cpp">//stonewt1.cpp--Stonewt class methods + conversion functions
#include <iostream>
using std::cout;
#include "stonewt1.h"
Stonewt::Stonewt(double lbs)
{
stone = int (lbs)/lbs_pr_stn;
pds_left = int (lbs)%lbs_pr_stn + lbs -int(lbs);
pounds = lbs;
}
Stonewt:: Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn * lbs_pr_stn + lbs;
}
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
}
Stonewt::~Stonewt()
{
}
void Stonewt::show_stn()const
{
cout << stone << " stone, " << pds_left << " pounds\n";
}
void Stonewt::show_lbs()const
{
cout << pounds << " pounds\n";
}
Stonewt::operator int()const
{
return int (pounds + 0.5);
}
Stonewt::operator double()const
{
return pounds;
}
demo.cpp
#include <iostream>
#include "stonewt1.h"
int main(int argc, char * argv [ ])
{
using std::cout;
Stonewt poppins(9,2.8);
double p_wt = poppins;
cout << "convert to double => ";
cout << "poppins: "<<p_wt<< " pounds.\n";
cout << "convert to int => ";
cout << "poppins: " << int (poppins)<<" pounds.\n";
return 0;
}
解析:
构造函数:
<span style="white-space:pre"> </span>Stonewt(double lbs);
用于将double类型的值转换为Stonewt类型,就是说可以这样编写代码:
<span style="white-space:pre"> </span>Stonewt myCat;
<span style="white-space:pre"> </span>myCat = 19.6;
程序将使用构造函数Stonewt(double)来创建一个临时的Stonewt对象,并将19.6作为初始值。随后,采用逐成员赋值的方式将该临时对象的内容复制到myCat中。
这一过程称为隐式转换,因为它是自动进行的,而不需要显示强制类型转换。不过这种自动转换并非总是合乎需求的,因此,可以使用一个关键字(explicit)来关闭这种自动特性。即可以这样声明构造函数:
<span style="white-space:pre"> </span>explicit Stonewt(double lbs);
这样将关闭上述范例中介绍的隐式转换,但允许强制类型转换:
<span style="white-space:pre"> </span>Stonewt myCat;
<span style="white-space:pre"> </span>myCat = Stonewt(19.6);
<span style="white-space:pre"> </span>myCat = (Stonewt)19.6;
注意:只接受一个参数的构造函数定义了从参数类型到类类型的转换。如果使用了关键字explicit限定了这种构造函数,则它只能用于显示转换,否则也可以用于隐式转换。
2.转换函数(强制类型转换)
上述程序将数字转换为Stonewt对象,其实也可将Stonewt对象转换为double值,但不是使用构造函数,必须使用特殊的C++操作符函数--转换函数。
转换函数的格式:
<span style="white-space:pre"> </span>operator typeName();
例如,转换为double类型的函数的原型如下:
<span style="white-space:pre"> </span>operator double();
解析:
typeName(这里为double)指出了要转换成的类型,因此不需要指定返回类型,转换函数是类方法意味着:它需要通过类对象来调用,从而告知函数要转换的值。因此,函数不需要参数。
注意:
转换函数必须是类方法。
转换函数不能指定返回类型。
转换函数不能有参数。
总结:
C++为类提供了下面的类型转换:
1.只有一个参数的类构造函数用于将类型与该参数相同的值转换为类类型。例如,将double值赋给Stonewt对象时,接受int参数的Stonewt类构造函数将自动被调用。不过,在构造函数声明中使用explicit可防止隐式转换,而只允许显示转换。
2.被称为转换函数的特殊类成员操作符函数,用于将类对象转换为其他类型。转换函数是类成员,没有返回类型、没有参数、名为operator typeName(),其中,typeName是对象将被转换成的类型。将类对象赋给typeName变量或将其强制转换为typeName类型时,该转换函数将被调用。