zoukankan      html  css  js  c++  java
  • C++ 构造转换函数和强制转换函数

    http://blog.csdn.net/chenyiming_1990/article/details/8862497

    1.对于系统的预定义基本类型数据,C++提供了两种类型转换方式:隐式类型转换和显式类型转换。

    1. int a=5,sum;  
    2. double b=5.55;  
    3. sum=a+b;//-------(1)  
    4. std::cout<<"隐式转换:a+b="<<sum<<std::endl;  
    5.    
    6. sum=(int)(a+b);//-------(2)  
    7. sum=int(a+b);//-------(3)  
    8. std::cout<<"显式转换:a+b="<<sum<<std::endl   


    上述代码中的(1)就是含有隐式类型转换的表达式,在进行"a+b"时,编译系统先将a的值5转换为双精度double,然后和b相加得到10.55,在向整形变量sum赋值时,将10.55转换为整形数10,赋值为变量sum。这种转换是C++编译系统自动完成,不需要用户去干预。而上例中的(2)和(3)中则涉及到了显式类型转换,它们都是把a+b所得结果的值,强制转化为整形数。只是(2)式是C语言中用到的形式:(类型名)表达式,而(3)式是C++中的采用的形式:类型名(表达式);

    2.那么对于用户自定义的类类型而言,有该如何去实现它们和其他数据类型之间的转换呢,C++中提供了两种方法:

    (1)通过转换构造函数进行类型转换;

    (2)通过类型转换函数进行类型转换;

    毫无疑问转换构造函数就是构造函数的一种,只不过它拥有类型转换的作用罢了。是否记得在C++之运算重载符(1)中两个复数(sum=com1+com2)相加的实例,现在如果我想要实现sum=com1+5.5,那该怎么办,也许你首先会想到再定义一个关于复数加双精度的运算符重载函数。这样做的确可以。另外我们还可以定义一个转换构造函数来解决上述的问题。我们对Comlex类(复数类)进行这样改造:

    1. #include <iostream>  
    2.    
    3. class Complex //复数类  
    4. {  
    5.     private://私有  
    6.     double real;//实数  
    7.     double imag;//虚数  
    8.     public:  
    9.         Complex(double real,double imag)  
    10.         {  
    11.             this->real=real;  
    12.             this->imag=imag;  
    13.         }  
    14.         Complex(double d=0.0)//转换构造函数  
    15.         {  
    16.             real=d;//实数取double类型的值  
    17.             imag=0;//虚数取0  
    18.         }  
    19.         Complex operator+(Complex com1);//或friend Complex operator+(Complex com1,Complex com2);  
    20.         void showComplex();  
    21. };  
    22.    
    23. Complex Complex::operator+(Complex com1)  
    24. {  
    25.     return Complex(real+com1.real,imag+com1.imag);  
    26. }  
    27.    
    28. void Complex::showComplex()  
    29. {  
    30.     std::cout<<real;  
    31.     if(imag>0)  
    32.         std::cout<<"+";  
    33.     if(imag!=0)  
    34.         std::cout<<imag<<"i"<<std::endl;  
    35. }  
    36.    
    37. int main()  
    38. {  
    39.    
    40.     Complex com(10,10),sum;  
    41.         sum = com + 5.5;//5.5调用Complex(5.5)生成临时对象,它的复数是5.5+0i  
    42.         sum.showComplex();//输出运算结果  
    43.     return 0;  
    44. }  


    结果:

    15.5 + 10i

    上述代码在执行5.5时,调用了转换构造函数,将double类型的5.5转换为无名的Complex类的临时对象(5.5+0i),然后执行两个Complex类(复数类)对象相加的运算符重载函数。所以说一般的转换构造函数的定义形式:

      类名(待转换类型)

      {

        函数体;

      }

    转换构造函数不仅可以将预定义的数据类型转换为自定义类的对象,也可以将另一个类的对象转换成转换构造函数所在的类的对象。

      转换构造函数可以把预定义类型转化为自定义类的对象,但是却不能把类的对象转换为基本数据类型。比如:不能将Complex类(复数类)的对象转换成double类型数据。于是在C++中就用类型转换函数来解决这个问题。定义类型转换函数一般形式:

      operator 目标类型()

      {

        ...

        return 目标类型的数据;

      }

    目标类型是所要转化成的类型名,既可以是预定义及基本类型也可以是自定义类型。

    类型转换函数的函数名(operator 目标类型)前不能指定返回类型

    没有参数

    但在函数体最后一条语句一般为return语句,返回的是目标类型的数据。

    现在我们对Complex类做类似改造:

    1. #include <iostream>  
    2.    
    3. class Complex //复数类  
    4. {  
    5.     private://私有  
    6.     double real;//实数  
    7.     double imag;//虚数  
    8.     public:  
    9.         Complex(double real,double imag)  
    10.         {  
    11.             this->real=real;  
    12.             this->imag=imag;  
    13.         }  
    14.         Complex(double d=0.0)//转换构造函数  
    15.         {  
    16.             real=d;//实数取double类型的值  
    17.             imag=0;//虚数取0  
    18.         }  
    19.         Complex operator+(Complex com1);//或friend Complex operator+(Complex com1,Complex com2);  
    20.         void showComplex();  
    21.         operator double();  
    22. };  
    23.    
    24. Complex Complex::operator+(Complex com1)  
    25. {  
    26.     return Complex(real+com1.real,imag+com1.imag);  
    27. }  
    28.    
    29. void Complex::showComplex()  
    30. {  
    31.     std::cout<<real;  
    32.     if(imag>0)  
    33.         std::cout<<"+";  
    34.     if(imag!=0)  
    35.         std::cout<<imag<<"i"<<std::endl;  
    36. }  
    37.   
    38. Complex::operator double()  
    39. {  
    40.     return real;   
    41. }  
    42.    
    43. int main()  
    44. {  
    45.     Complex com(10,10);   
    46.     double total1,total2;  
    47.     total1 = double(com) + 5.5;//double(com)把复数(10+10i)转换为双精度数10.0  
    48.     total2 = 5.5 + com; // 写成 total2 = com + 5.5 是错误的   
    49.     std::cout<<"把Complex类显式对象转化为double类型与5.5相加为:"<< total1 << std::endl;   
    50.     std::cout<<"把Complex类对象隐式转化为double类型与5.5相加为:"<< total2 << std::endl;   
    51.     return 0;  
    52. }  

    说明:

    total2 = 5.5 + com;  com自动调用转换函数进行转换(如果5.5 改为5,并且还定义有operator long() 类型转换,将出现编译错误,因为int 既可以转换为long ,也可以转换为 double,编译器会报错)。

    为什么  total2 = com  + 5.5; 不行呢?

    这是会出现歧义:

    是com 用转换函数变为double型,进行double定义的加法

    还是 5.5 利用转换构造函数变为Complex临时变量,进行 Complex定义的加法,就不清楚了

    所以进行显示的转换:

    1. total = (double)com + 5.5  


    3.最后对类型转换函数做几点补充:

    (1)类型转换函数只能作为类的成员函数,不能定义为类的友元函数;

    (2)类型转换函数中必须有return语句,即必须送回目标类型的数据作为函数返回值;

    (3)一个类可以定义多个类型转换函数,C++编译器会根据函数名来自动调用相应的类型转换函数函数

  • 相关阅读:
    Android-TabLayout设置内容宽度以及下划线宽度
    RecyclerView 上拉加载下拉刷新
    Android自定义View实现仿QQ实现运动步数效果
    Android开发中常见的内存泄露案例以及解决方法总结
    Android封装TitleBar基本适用所有常规开发
    Activity设置背景透明之开发坑
    Android表情开发
    订制EditText光标
    Android:java.lang.OutOfMemoryError:GC overhead limit exceeded
    Android之自定义View学习(一)
  • 原文地址:https://www.cnblogs.com/forcheryl/p/3955407.html
Copyright © 2011-2022 走看看