C++重载类型转换操作符

http://blog.csdn.net/yby4769250/article/details/7332449

 

在需要做数据类型转换时,一般显式的写法是:

 

    type1 i;  
    type2 d;  
    i = (type1)d; //显式的写类型转,把d从type2类型转为type1类型</span>  

 

这种写法不能做到无缝转换,也就是直接写 i = d,而不需要显式的写(type1)来向编译器表明类型转换,要做到这点就需要介绍一下“类型转换操作符”,拿最简单的基本类型封包解包来举例:

 1     class Integer  
 2     {  
 3     public:  
 4         Integer(int v);  
 5         Integer& opetaror =(const int &v); //重载赋值操作符,可以做到 Integer i = 10;//把i当基本数据类型使用  
 6         operator int(); //重载类型转换操作符,可以做到int i; Integer it;  i = it; //it直接转为int类型,然后赋值给i  
 7       
 8     private:  
 9         int data;  
10     };  
11     Integer::Integer(int v)  
12     {  
13         data = v;  
14     }  
15       
16     /*! 
17      *重载赋值操作符,可以做到 Integer i = 10;//把i当基本数据类型使用 
18      */  
19     Integer& Integer::opetaror =(const int &v)  
20     {  
21         data = v;  
22         return *this;  
23     }  
24       
25     /*! 
26      *重载类型转换操作符,可以做到int i; Integer it;  i = it; //it直接转为int类型,然后赋值给i 
27      */  
28     Integer::operator int()  
29     {  
30         return data;  
31     }  
32       
33     #include <iostream>  
34     using namespace std;  
35       
36     int main()  
37     {  
38         Integer integer1(10); //调用构造函数进行初始化  
39         Integer integer2;  
40         int i1 = 10;  
41         integer2 = i1; //调用=赋值操作符进行赋值  
42       
43         //下面测试类型转换操作符的应用  
44         int i2;  
45         i2 = integer1; //integer1是Integer类型,这里直接把Integer类型转换为int,然后赋值给i2  
46                               //如果没有重载了int(),需要类型转换的话,这里必须写成 i2 = (int)integer1;  
47         return 0;  
48     }  

这是int类型转换的写法,相应的,long,float,double等等的类型转换方法一样,统一的说,可以抽象的写成

operator type();只要type是一个类型,包括基本数据类型,自己写的类或者结构体都可以转换。


 


下面一段转载,清楚的写明了重载类型转换需要注意的问题

原文链接重载类型转换操作符 遇到的问题


转换函数采用如下通用形式:

operator type();

这里,type表示内置类型名、类类型名或有类型别名所定义的名字。对任何可作为函数的返回类型(除了void之外)。一般而言,不允许转换为数组或函数类型,转换为指针类型(数据和函数指针)以及引用类型是可以的。

注解: 转换函数必须是成员函数不能指定返回类型,并且形参表必须为空

下述所有的声明都是错误的:

 1 operator int(Small Int& ); // error:nonmember
 2 
 3 class SmallInt
 4 
 5 {
 6 
 7 public:
 8 
 9 int operator int(); // error: return list
10 
11 operator int(int = 0);  // error:parameter list
12 
13 // ...
14 
15 };

虽然转换函数不能指定返回类型,但是每个转换函数必须显示返回一个指定的值。例如,operator int返回一个int值;如果定义operator Sales_item,它将返回一个Sales_item对象,诸如此类。

最佳实践: 转换函数一般不应该改变被转换的对象。因此,转换操作符通常应定义为const成员

1、使用类类型转换

只要存在转换,编译器将在可以使用内置转换的地方自动调用

在表达式中:

1 SmallInt si;
2 
3 double dval;
4 
5 si >= dval // si converted to int and then convert to bool

在条件中:

1 if(si) // si convert to int and then convert to bool

将实参传给函数或 从函数返回值:

1 int calc(int);
2 
3 SmallInt si;
4 
5 int i = calc(si); // convert si to int and call calc

作为重载操作符的操作数:

1 // convert si to int then call << on the int value
2 
3 cout << si << endl;

在显示类型转换中:

1 int ival;
2 
3 SmallInt si = 3.54;
4 
5 // instruct compiler to cast si to int
6 
7 ival = static_cast<int>(si) + 3;

2、类类型转换和标准转换

使用转换函数时,被转换的类型不必与所在需要的类型完全匹配。必要时可在类类型转换之后跟上标准转换以获得想要的类型。例如,在一个SmallInt对象与一个double值的比较中:

1 SmallInt si;
2 
3 double dval;
4 
5 si >= dval // si converted to int and then convert to double.

首先将si从SmallInt对象转换为int值,然后将该int值转换为double值。

3、只能应用一个类类型转换

注解:类类型转换之后再跟另一个类类型转换。如果需要多个类类型转换,则代码将出错。

例如,假定有一个类Integral,它可以转换为SmallInt但不能转换为int:

 1 // class to hold unsigned integral values
 2 
 3 class Integral
 4 
 5 {
 6 
 7 public:
 8 
 9 Integral(int i = 0):val(i)
10 
11 {
12 
13 }
14 
15 operator SmallInt()const
16 
17 {
18 
19 return val % 256;
20 
21 }
22 
23 private:
24 
25 std::size_t val;
26 
27 };

可以在需要SmallInt的地方使用Integral,但不能再需要int的地方使用Integral:

1 int calc(int);
2 
3 Integral intVal;
4 
5 SmallInt si(intVal); // ok:convert intVal to Small Int and copy to si
6 
7 int i = calc(si);  // ok:convert si to int and call calc
8 
9 int j = calc(intVal);// error:on convertion to int from Integral

创建si时使用SmallInt复制构造函数。首先调用Integral转换操作符产生一个SmallInt类型的临时值,将int_val对象转换为SmallInt对象。然后(合成的)复制构造函数使用该对象值初始化si。

第一个calc调用也是正确的:将实参si自动转换为int,然后将int值传给函数。

第二个calc调用时错误的:没有从Integral到int的直接转换。从Intergral获得int需要两次类类型转换:首先从Intergral到SmallInt,然后从SmallInt到int。但是,语言只是允许一个类类型转换,所以该调用出错。

4.标准转换可放在类类型转换之前

使用构造函数执行隐式转换的时候,构造函数的形参类型不必与所提供的类型完全匹配。例如,下面的代码调用SmallInt类中定义的构造函数SmallInt(int)将sobj转换为SmallInt类型:

1 void calc(SmallInt);
2 
3 short sobj;
4 
5 // sobj prometed from short to int 
6 
7 // that int converted to SmallInt through the SmallInt(int) constructor
8 
9 calc(sobj);

如果需要,在调用构造函数执行类类型转换之前,可将一个标准转换序列应用于实参。为了调用函数calc(),应用标准转换将dobj从double类型转换为int类型,然后调用构造函数SmallInt(int)将转换结果转换为SmallInt类型。

posted on 2017-01-23 22:09  zhangyz017  阅读(312)  评论(0编辑  收藏  举报

导航