类型转换函数
我们都知道,对于基本数据类型的数据可以通过强制类型转换操作符来将数据转换成需要的类型,例如static_cast<int>(2.1),这个表达式将实型数据2.1转换成了int类型数据。那么对于自定义的类来说,在很多情况下也需要支持此操作来实现自定义类与基本数据类型之间的转换,对此C++提供了类型转换函数。
类型转换函数也称为类型转换运算符重载函数,其基本格式如下所示:
operator 类型名();
类型转换函数也是以operator关键字开头,这点和运算符重载时的规律是一致的,只是被重载的是类型名。在函数名前面不能指定函数类型,函数也没有参数。其返回值的类型是由函数名中指定的类型名来确定的(如果类型名为double,则将类类型数据转换为double类型返回)。类型转换运算符重载函数只能作为类的成员函数,因为转换的主体是本类的对象。
接下来我们通过一个案例来演示类型转换运算符重载,定义一个Swap类,将Swap类类型的对象转换为char类型,具体代码如例1所示。
例1
1 #include <iostream>
2 using namespace std;
3 class Swap
4 {
5 private:
6 int a, b;
7 public:
8 Swap(int m, int n) :a(m), b(n){}
9 operator char() //类型转换运算符重载函数
10 {
11 return static_cast<char>(a);
12 }
13 void show()
14 {
15 cout << a << " " << b << endl;
16 }
17 };
18
19 int main()
20 {
21 Swap s1(65, 2); //调用普通构造函数创建对象
22 cout << "s1: ";
23 s1.show();
24 char ch = s1; //调用类型转换函数
25 cout << ch << endl;
26
27 system("pause");
28 return 0;
29 }
运行结果如图1所示。
图1 例1运行结果
在例1中定义了类型转换函数,将Swap类类型的对象转换为char类型,由图4-9所知,转换成功,s1对象成功转换为了字符’A’。
值得一提的是,类型转换运算符有一个功能。 当需要的时候,编译系统会自动调用重载函数,建立一个无名的临时对象(或临时变量)。例如例4-8中,将s1对象赋值给ch时,如果没有重载“=”运算符,编译器首先会检查是否有类型转换函数,如果有,则调用operator char()函数将s1对象转换为一个临时的char类型变量,再将这个临时变量赋值给ch。
多学一招:转换构造函数
自定义数据类型与基本数据类型之间的转换,除了类型转换运算符重载,还可以定义转换构造函数。所谓转换构造函数就是当一个构造函数只有一个参数,而且该参数又不是本类的const引用时,这种构造函数称为转换构造函数。用转换构造函数不仅可以将一个标准类型数据转换为类对象,也可以将另一个类的对象转换为转换构造函数所在的类对象。使用转换构造函数将一个指定数据转换为类对象的方法如下所示:
(1)先声明一个类。
(2)在这个类中定义一个转换构造函数,在函数体中指定转换方法。
(3)在该类的作用域内可以用以下形式进行类型转换:
类名(指定类型的数据);
上述形式不仅可以将一个标准类型数据转换成类对象,也可以将另一个类的对象转换成转换构造函数所在的类对象。例如将一个学生类(Student)对象转换成教师(Teacher)类对象,可以在Teacher类中定义如下的转换构造函数:
Teacher(Student& s)
{
num = s.num;
strcpy(name, s.name);
}
注意:对象s中的num、name必须是公有成员,否则不能被类外引用。
为了加深读者的理解,我们用转换构造函数来改写例1中基本数据与类类型之间的转换,具体代码如例2所示。
例2
1 #include <iostream>
2 using namespace std;
3 class Swap
4 {
5 private:
6 int a, b;
7 public:
8 Swap(int m, int n) :a(m), b(n){}
9 Swap(double c) //转换构造函数
10 {
11 cout << "swap constructor is calling" << endl;
12 a = static_cast<int>(c);
13 b = 0;
14 }
15 void show()
16 {
17 cout << a << " " << b << endl;
18 }
19 };
20 int main()
21 {
22 Swap s1(1, 2); //调用普通构造函数创建对象
23 Swap s2(3.2); //调用转换构造函数
24 cout << "s1: ";
25 s1.show();
26 cout << "s2: ";
27 s2.show();
28
29 system("pause");
30 return 0;
31 }
运行结果如图2所示。
图2 例2运行结果
在例2中,定义了一个转换构造函数,将double类型的数据转换类Swap类类型,在创建对象s2时,将3.2转换成了Swap类类型。与类型转换函数一样,在将double类型数据3.2转换成Swap类型时,先调用转换构造函数将3.2转换成一个临时的Swap类对象,然后将这个临时对象赋值给对象s2。
用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Swap类对象转换成double类型数据)。如果要这么做,则需要类型转换函数。