1. 程式人生 > >C++運算子過載補充之不同資料間的型別轉換

C++運算子過載補充之不同資料間的型別轉換

尊重原創:http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/14/2137790.html

  我們在使用過載的運算子時,往往需要在自定義資料型別和系統預定義的資料型別之間進行轉換,或者需要在不同的自定義資料型別之間進行轉換。今天就來講講C++中資料型別的轉換。
  1.對於系統的預定義基本型別資料,C++提供了兩種型別轉換方式:隱式型別轉換和顯式型別轉換。

int a=5,sum;
double b=5.55;
sum=a+b;//-------(1)
std::cout<<"隱式轉換:a+b="<<sum<<std::endl;
 
sum=(int)(a+b);//-------(2)
sum=int(a+b);//-------(3)
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 "stdafx.h"
2 #include <iostream>
3 
4 class Complex //複數類
5 {
6 private://私有
7 double real;//實數
8 double imag;//虛數
9 public:
10 Complex(double real,double imag)
11 {
12 this->real=real;
13 this->imag=imag;
14 }
15 Complex(double d=0.0)//轉換建構函式
16 {
17 real=d;//實數取double型別的值
18 imag=0;//虛數取0
19 }
20 Complex operator+(Complex com1);//或friend Complex operator+(Complex com1,Complex com2);
21 void showComplex();
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 int main()
39 {
40 
41 Complex com(10,10),sum;
42 sum=com+Complex(5.5);//Complex(5.5)把雙精度數5.5轉換為複數5.5+0i
43 sum.showComplex();//輸出運算結果
44 
45 return0;
46 }
上述程式碼在執行Complex(5.5)時,呼叫了轉換建構函式,將double型別的5.5轉換為無名的Complex類的臨時物件(5.5+0i),然後執行兩個Complex類(複數類)物件相加的運算子過載函式。所以說一般的轉換建構函式的定義形式:

  類名(待轉換型別)

  {

    函式體;

  }

轉換建構函式不僅可以將預定義的資料型別轉換為自定義類的物件,也可以將另一個類的物件轉換成轉換建構函式所在的類的物件。
  轉換建構函式可以把預定義型別轉化為自定義類的物件,但是卻不能把類的物件轉換為基本資料型別。比如:不能將Complex類(複數類)的物件轉換成double型別資料。於是在C++中就用型別轉換函式來解決這個問題。定義型別轉換函式一般形式:

  operator 目標型別()

  {

    ...

    return 目標型別的資料;

  }

目標型別是所要轉化成的型別名,既可以是預定義及基本型別也可以是自定義型別。型別轉換函式的函式名(operator 目標型別)前不能指定返回型別,且沒有引數。但在函式體最後一條語句一般為return語句,返回的是目標型別的資料。現在我們對Complex類做類似改造:
1 #include "stdafx.h"
2 #include <iostream>
3 
4 class Complex //複數類
5 {
6 private://私有
7 double real;//實數
8 double imag;//虛數
9 public:
10 Complex(double real,double imag)
11 {
12 this->real=real;
13 this->imag=imag;
14 }
15 Complex(double d=0.0)//轉換建構函式
16 {
17 real=d;//實數取double型別的值
18 imag=0;//虛數取0
19 }
20 
21 Complex operator+(Complex com1);//或friend Complex operator+(Complex com1,Complex com2);
22 operatordouble();//宣告型別轉換函式
23 void showComplex();
24 };
25 
26 Complex Complex::operator+(Complex com1)
27 {
28 return Complex(real+com1.real,imag+com1.imag);
29 }
30 
31 Complex::operatordouble()//定義型別轉換函式
32 {
33 return real;//返回實數部分
34 }
35 
36 void Complex::showComplex()
37 {
38 std::cout<<real;
39 if(imag>0)
40 std::cout<<"+";
41 if(imag!=0)
42 std::cout<<imag<<"i"<<std::endl;
43 }
44 
45 
46 
47 int main()
48 {
49 
50 Complex com(10,10),sum;
51 sum=com+Complex(5.5);//Complex(5.5)把雙精度數5.5轉換為複數5.5+0i
52 sum.showComplex();//輸出運算結果
53 
54 double total;
55 total=double(com)+5.5;//double(com)把複數(10+10i)轉換為雙精度數10.0
56 std::cout<<"把Complex類物件轉化為double型別與5.5相加為:"<<total;
57 
58 return0;
59 }
  3.最後對型別轉換函式做幾點補充:(1)型別轉換函式只能作為類的成員函式,不能定義為類的友元函式;(2)型別轉換函式中必須有return語句,即必須送回目標型別的資料作為函式返回值;(3)一個類可以定義多個型別轉換函式,C++編譯器會根據函式名來自動呼叫相應的型別轉換函式函式;