正文 第十章 運算符重載與類型轉換函數(1 / 3)

本章將要介紹Visual C++的另一個重要方法——運算符重載。

10.1運算符重載的概念

Visual C++允許將運算符重新定義以符合程序的需要。運算符重載的概念在C語言中就存在。

由此可見,一個運算符可以有多種含義,而用戶在使用時,並不需要特別指明引用該運算符的哪一個功能,編譯器會根據運算符作用的操作數,自動判斷應該對運算符賦予哪一種含義,這就是運算符重載的概念。

我們來看看Vi8UalC++的編譯器遇到上述情況,是如何處理運算符的。

當編譯器分析表達式

a*b時,會把它解釋為如下形式:operator*(a*b)其中,operator是一個關鍵字,它經常和運算符聯用,表示一個運算符函數名。因此,該表達式實際調用函數operator*(int),a和b是它的實際參數。同樣,*add會被解釋為operator*(add),它實際調用operator*(int*)0Visual C++已經為各種數據類型重載運算符函數operator*(),這些重載的形式包括:operator*(int,int);operator*(int*);

當我們使用運算符*時,Visual C++根據重載函數的原則調用相應的重載形式。

在Visual C++中,可以像重載普通函數那樣,重載運算符函數。例如,當我們重載operator*()函數時,就叫做重載運算符*。Visual C++中的運算符大多數都能夠被重載,隻有很少一部分不能被重載。能夠被重載的運算符按使用操作數的個數可分為:

單、雙目運昇符使用一個或兩個操作數都可以,例如,a*b(來法),*ptr(取地址的內容)。

10.2實現運算符重載

一、運算符重載的時機

我們來看一個例子,了解應該在什麼時候使用運算符重載。

在程序中我們定義了一個表示複數數據類型的類Complex,複數是由實數部分和虛數部分組成,在類Complex中,我們以real數據成員表示複數的實數,而imag表示複數的虛數部分。程序中提供了兩個實現複數相加的函數add(),一個為成員函數,一個為友元函數。

注意本例的構造函數的參數都帶有缺省值,以本身也可以當做缺省構造函數。

類Complex是一種數學數據類型,因此可以像其他的數學數據類型做四則運算,例如整數的相加減:

可是,由於類Complex不是C++內建的數據類型(如int、float等),所以類Complex的對象不能使用上麵的語句形式。

我們在程序中定義了兩個可以做複數類型加減的成員函數add和sub。注意,複數的加減是實數與實數部分做運算,虛數與虛數部分做運算。函數81(1和811)都返回一個Com-plex類型的對象,它的值是複數加減後的結果。由main()函數來看一下本程序中是如何實現複數相加的。

該語句通過調用對象cl的成員函數add()來完成複數相加。相減運算也是如此。這樣的語句雖然可以得到預期的結果,但是在表達與使用上還不是很理想。為此,我們又提供了另外一個完成複數相加的函數add(),它是類的友元。這樣,複數相加便表示成c3=add(cl+c2);的形式,在使用上比前一種形式更直觀一些,但是濟究不如直接使用運算符來得清楚。最好的辦法是使用運算符重載,將運算符+與-重i定義;使其能夠作用於Complex對象上,複數相加減。

二、成員運算符函數運算符重載是通過調用運算符函數來實現的,運算符函數的形式。

其中op表示欲重載的運算符,必須是C++中已經定義的運算符,不可以自定義新的符號。在運算符前麵必須加上關鍵字operator用以表示該函數為運算符函數。參數表有多種表現形式,要根據具體情況而定,以後再逐步說明。

在說明一個運算符函數時,如果參數為類類型,為了能夠訪問這個類的私有成員,可以將一個運算符函數說明為這個類的成員函數,稱之為成員運算符函數;或把它說明為這個類的友元函數。稱之為友元運算符函數。在C++中,大部分的運算符既可以重載為成員運算符函數,也可以重載為友元運算符函數。

下麵我們來看一個例子。

在本程序中,可以直接使用運算符來實現類Complex對象的加減運算。注意,我們重新定義了成員函數Show(),使輸出結果更加直觀。

下麵以運算符+為例,看一看使用寧算符函數是如何實現這一目的的。

在例10.1中以函數add()來表示Complex對象的相加,而在例10.2中以運算符函數來重新定義運算符+,使其具有與函數add()的一樣的功能。

通過比較我們發現,當以運算符函數代替原來的add()函數時,隻需將原來的函數名稱改成operator+(關鍵字接上欲重定義的運算符+)。

在使用運算符函數時不必寫出關鍵字operator,並且不必指明通過對象cl來調用運算符函數。

我們要習慣於將operat0r+看成是一個函數名。

注意,運算符+在此為雙目運算符,需要兩個操作數,但由於運算符函數是類Com-plex的成員函數,它包含一個隱含的參數this,this指針指向訪問該成員函數(運算符函數)的活動對象,因此,運算符函數隻需要一個參數,另一個操作教來自活動對象,不需要在參數表中指明

三、友元運算符函數

下麵的例子使用了友元函數重載類Complex中的運算符+和-。