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++编译器会根据函数名来自动调用相应的类型转换函数函数

  • 相关阅读:
    VS2008 环境中完美搭建 Qt 4.7.4 静态编译的调试与发布 Inchroy's Blog 博客频道 CSDN.NET
    编写可丢弃的代码
    c++ using namespace std; 海明威 博客园
    解决MySQL server has gone away
    nginx upstream 调度策略
    (2006, 'MySQL server has gone away') 错误解决 dba007的空间 51CTO技术博客
    Linux IO模型漫谈(2) 轩脉刃 博客园
    redis源码笔记 initServer 刘浩de技术博客 博客园
    MySQLdb批量插入数据
    词库的扩充百度百科的抓取你知道这些热词吗? rabbit9898 ITeye技术网站
  • 原文地址:https://www.cnblogs.com/forcheryl/p/3955407.html
Copyright © 2011-2022 走看看