类型转换

大多数程序都可以处理各种数据类型的信息,有时所有操作会集中在同一种类型。但是,在很多情况下都需要将一种类型的数据转换为另一种类型的数据。

系统预定义类型之间的转换

C++规定,当不同类型的数据进行运算时,需先将数据转换成同一类型,然后才可以进行运算。数据的类型转换可以通过两种转换形式完成:一种是隐式类型转换,另一种是显式类型转换。
1、数据类型的隐式转换
当执行赋值表达式V=E时,如果V和E的类型不一致,则将E先转换为V后再赋值。
2、数据类型的显式转换
显式类型转换有两种方式:
强制转换法: (类型名)表达式 例如:(float) (5%2)
函数法:类型名(表达式) 例如:float (a+b);

用构造函数实现类型转换

用构造函数完成类类型转换,类内至少定义一个只带一个参数(没有其他参数,或其他参数都有默认值)的构造函数。当进行类型转换时,系统会自动调用该构造函数,创建该类的一个临时对象,该对象由被转换的值初始化,从而实现类型转换。

  1. #include <iostream>
  2. #include <string.h>
  3. using namespace std;
  4. class String
  5. {
  6. private:
  7. char *str;
  8. int length;
  9. public:
  10. String(char *in_str); 声明了一个转换构造函数
  11. ~String();
  12. void showstring();
  13. };
  14. String::String(char *in_str)
  15. {
  16. length = strlen(in_str);
  17. str = new char[length+1];
  18. strcpy(str, in_str);
  19. }
  20. String::~String()
  21. {
  22. delete []str;
  23. }
  24. void String::showstring()
  25. {
  26. cout << str <<endl;
  27. }
  28. int main()
  29. {
  30. String s = (char*)"C/C++ Program";
  31. s.showstring();
  32. return 0;
  33. }
  34. String(char *in_str);//声明了一个转换构造函数,
  35. 该构造函数可以用来进行类型转换。main函数中,在执行String s = (char*)"C/C++ Program";时,
  36. 编译系统首先调用构造函数建立包含C/C++ Program的一个临时string对象,然后再将该临时string对象赋给赋给对象s
  37. 使用这种转换构造函数意味着不用再为了要将字符串赋给string类对象提供重载的赋值操作符,
  38. 因为基本操作符“=”是不允许将一个char*字符串赋给一个string类对象的。
  39. 任何只带一个参数(或其他参数都带有默认值)的构造函数都可以认为是一种转换构造函数
#include <iostream>
using namespace std;

class Complex
{
    private:
        double real,imag;
    public:
        Complex();
        Complex(int r);
        Complex(double r, double i);
        void Print();
        friend Complex operator+(Complex a, Complex b);
};

Complex::Complex()
{
    real = imag = 0;
}

Complex::Complex(int r)
{
    real = r;
    imag = 0;
}


Complex::Complex(double r, double i)
{
    real = r;
    imag = i;
}

Complex operator+(Complex a, Complex b)
{
    Complex temp;
    temp.real = a.real + b.real;
    temp.imag = a.imag + b.imag;
    return temp;
}

void Complex::Print()
{
    cout <<real;
    if(imag > 0)
        cout << "+";
    if(imag != 0)
        cout << imag << "i" <<endl;
}

int main()
{
    Complex com1(1.1, 2.2), com2, com3 = 10;
    cout << "com1:";
    com1.Print();
    com1 = 20 + com1;
    cout << "com1=20+com1:" <<endl;
    com1.Print();
    com2 = 10 + 200;
    cout << "com2=10+200:" <<endl;
    com2.Print();
    cout <<endl;
    cout << "com3=10:" <<endl;
    com3.Print();
    cout <<endl;
    return 0;
}
编译程序再分析赋值表达式com3 = 10时,根据隐式类型转换规则,要将整数10转换为com3的类型,这就通过调用构造函数Complex(int r)完成所需要的类型转换。
分析com1 = 20 + com1;时,编译程序首先调用构造函数Complex(int r)将整数20转换成Complex类型,然后再调用运算符函数operator+完成两个Complex类型数据的加法运算,最后再赋值。
分析com2 = 10 + 200时,编译器首先完成整数的加法运算,然后再调用构造函数Complex(int r)将整型数210转换成Complex类型,最后再赋值。

用类类型转换函数进行类型转换

用运算符转换函数实现类型转换
使用构造函数可以实现类型转换,但是其所完成的类型转换功能具有一定的局限性。由于无法为系统预定义类型定义构造函数,只能实现系统预定义类型向自定义的类类型转换。

class 源类类名
{
//……
   operator 目的类型()
   {
      //……
              return 目的类型的数据;
   }
//……
};

使用类类型转换函数,需要注意:
1)类类型转换函数只能定义为一个类的成员函数,而不能定义为类的友元函数
2)类类型转换函数既没有参数,也不显示给出返回类型
3)类类型函数中必须有return 目的类型的数据的语句,即必须返回目的类型数据作为函数的返回值

#include <iostream>
using namespace std;

class Complex
{
    private:
        double real,imag;
    public:
        Complex(double r = 0, double i = 0);
        operator float();//类类型转换函数
        operator int();//同类类型转换函数,没有参数,没有返回类型
        void Print();
};

Complex::Complex(double r, double i)
{
    real = r;
    imag = i;
    cout << "Constructing..." <<endl;
}

Complex::operator float()
{
    cout << "Type changed to float" <<endl;
    return real;
}

Complex::operator int()
{
    cout << "Type changed to int" <<endl;
    return int(real);
}

void Complex::Print()
{
    cout << "(" <<real << "," << imag << ")" <<endl;
}

int main()
{
    Complex a(1.1, 2.2);
    a.Print();
    cout << float(a)*0.5 <<endl;
    Complex b(4.7, 6);
    b.Print();
    cout << int(b)*2 <<endl;
    return 0;
}
#include <iostream>
using namespace std;

class Complex
{
    private:
        double real,imag;
    public:
        Complex(double r, double i);
        Complex(double i = 0);
        operator double();
        void Print();
};

Complex::Complex(double r, double i)
{
    real = r;
    imag = i;
}

Complex::Complex(double i)
{
    real = imag = i;
}

Complex::operator double()
{
    cout << "Type changed to double" <<endl;
    return real+imag;
}

void Complex::Print()
{
    cout << "(" <<real << "," << imag << ")" <<endl;
}

int main()
{
    Complex a(1.1, 2.2), b(2.3, 3.2), c;
    c = a + b;
    c.Print();    
    return 0;
}
#include <iostream>
using namespace std;

class Vector
{
    private:
        double x,y;    
    public:
        Vector(double tx = 0, double ty = 0);
        void print();
};

class Complex
{
    private:
        double real,imag;
    public:
        Complex(double r = 0, double i = 0);
        operator Vector();
};

Complex::Complex(double r, double i)
{
    real = r;
    imag = i;
}

Complex::operator Vector()
{
    return Vector(real, imag);
}

Vector::Vector(double tx, double ty)
{
    x = tx;
    y = ty;
}

void Vector::print()
{
    cout << "(" << x << "," << y << ")" <<endl; 
}

int main()
{
    Vector v;
    Complex a(1.1, 2.2);
    v = a;
    v.print();
    return 0;
}