用戶自定義類(class)類型可以當作系統內建類型(build-in type)來處理,對這一點我一直很驚奇,也很迷惑,特別是在類定義、繼承關系很復雜的時候,要找到來龍去脈真的很抓頭。最近工作中碰到這一塊的東西,順便借這個機會澄清一些概念。
看下面代碼:
1 class CBase {
2 public:
3 CBase()
4 {
5 cout << "CBase constructor()" << endl;
6 }
7 virtual ~CBase()
8 {
9 cout << "CBase destructor()" << endl;
10 }
11
12 operator long()
13 {
14 cout << "CBase::operator long()" << endl;
15 return 0;
16 }
17
18 operator char()
19 {
20 cout << "CBase::operator char()" << endl;
21 return 'a';
22 }
23 }
24 ;
25 class CDerived:public CBase
26 {
27 public:
28 CDerived()
29 {
30 cout << "CDerived constructor()" << endl;
31 }
32
33 virtual ~CDerived()
34 {
35 cout << "CDerived destructor()" << endl;
36 }
37
38 operator long()
39 {
40 cout << "CDerived::operator long()" << endl;
41 //return CBase::operator long();
return *((CBase *)this);//change the above code to this looks better
42 }
43
44 };
45
46 void main()
47 {
48 CDerived d;
49 long lTmp = d;
50 cout << "lTmp=" << lTmp << endl;
51 char cTmp = d;
52 cout << "cTmp=" << cTmp << endl;
53
54 }
由于定義了操作符重載CDerived::operator long() 和CBase::operator long(),49行得以編譯通過。同理,定義了CBase::operator char(),51行可以編譯。
執行結果為:
CBase constructor()
CDerived constructor()
CDerived::operator long()
CBase::operator long()
lTmp=0
CBase::operator char()
cTmp=a
CDerived destructor()
CBase destructor()
這里涉及到的概念主要有:
1 類成員操作符重載(使得用戶定義類型轉換為內建類型成為可能。對于用戶定義類型之間的轉換,還可以通過構造函數的方式進行)
2 自動類型轉換。自動類型轉換發生的情況有以下幾種:
函數調用時傳遞的實參類型與函數聲明中指定的參數類型不匹配
函數返回的對象類型與函數聲明中指定的返回類型不匹配
表達式中操作數的類型不一致(這正是上面例子中的情況)
有意思的是,即使不定義CBase::operator char(),上面的51行仍能通過,真得感嘆編譯器的聰明才智了,或許只是編譯器source中多了一些的if{}else{}呢?