C++中預定義的運算符的操作對象只能是基本數據類型。但實際上,對於許多用戶自定義類型(例如類),也需要類似的運算操作。這時就必須在C++中重新定義這些運算符,賦予已有運算符新的功能,使它能夠用於特定類型執行特定的操作。運算符重載的實質是函數重載,它提供了C++的可擴展性,也是C++最吸引人的特性之一。
運算符重載是通過創建運算符函數實現的,運算符函數定義了重載的運算符將要進行的操作。運算符函數的定義與其他函數的定義類似,惟一的區別是運算符函數的函數名是由關鍵字operator和其後要重載的運算符符號構成的。運算符函數定義的一般格式如下:
<返回類型說明符> <運算符符號>(<參數表><函數體>
運算符重載時要遵循以下規則:
(1) 除了類屬關系運算符"."、成員指針運算符".*"、作用域運算符"::"、sizeof運算符和三目運算符"?:"以外,C++中的所有運算符都可以重載。
運算符函數重載一般有兩種形式:重載為類的成員函數和重載為類的非成員函數。非成員函數通常是友元。(可以把一個運算符作為一個非成員、非友元函數重載。但是,這樣的運算符函數訪問類的私有和保護成員時,必須使用類的公有接口中提供的設置數據和讀取數據的函數,調用這些函數時會降低性能。可以內聯這些函數以提高性能。)
成員函數運算符
運算符重載為類的成員函數的一般格式為:<函數類型> <運算符>(<參數表><函數體>
當運算符重載為類的成員函數時,函數的參數個數比原來的操作數要少一個(後置單目運算符除外),這是因為成員函數用this指針隱式地訪問了類的一個對象,它充當了運算符函數最左邊的操作數。因此:
(1) 雙目運算符重載為類的成員函數時,函數只顯式說明一個參數,該形參是運算符的右操作數。<對象名>. <運算符>(<參數><對象名><運算符><參數>+b等價於a. +(b)。一般情況下,我們采用運算符的習慣表達方式。
運算符重載為類的友元函數的一般格式為:
friend <函數類型> <運算符>(<參數表><函數體>
當運算符重載為類的友元函數時,由於沒有隱含的this指針,因此操作數的個數沒有變化,所有的操作數都必須通過函數的形參進行傳遞,函數的參數與操作數自左至右一一對應。
<運算符>(<參數1>,<參數2><參數1><運算符><參數2>+b等價於operator +(a,b)。
在多數情況下,將運算符重載為類的成員函數和類的友元函數都是可以的。但成員函數運算符與友元函數運算符也具有各自的一些特點:
(1) 一般情況下,單目運算符最好重載為類的成員函數;雙目運算符則最好重載為類的友元函數。