原博客:http://www.cnblogs.com/speedmancs/archive/2011/06/09/2076873.html
operator是C++的關鍵字,它和運算符一起使用,表示一個運算符函數,理解時應將operator=整體上視為一個函數名。
這是C++擴展運算符功能的方法,雖然樣子古怪,但也可以理解:
一方面要使運算符的使用方法與其原來一致,另一方面擴展其功能只能通過函數的方式(c++中,“功能”都是由函數實現的)。
一、為什么使用操作符重載?
對於系統的所有操作符,一般情況下,只支持基本數據類型和標准庫中提供的class,對於用戶自己定義的class,如果想支持基本操作,比如比較大小,判斷是否相等,等等,則需要用戶自己來定義關於這個操作符的具體實現。比如,判斷兩個人是否一樣大,我們默認的規則是按照其年齡來比較,所以,在設計person 這個class的時候,我們需要考慮操作符==,而且,根據剛才的分析,比較的依據應該是age。
那么為什么叫重載呢?這是因為,在編譯器實現的時候,已經為我們提供了這個操作符的基本數據類型實現版本,但是現在他的操作數變成了用戶定義的數據類型class,所以,需要用戶自己來提供該參數版本的實現。
二、如何聲明一個重載的操作符?
A: 操作符重載實現為類成員函數
重載的操作符在類體中被聲明,聲明方式如同普通成員函數一樣,只不過他的名字包含關鍵字operator,以及緊跟其后的一個c++預定義的操作符。
可以用如下的方式來聲明一個預定義的==操作符:
1 class person{ 2 private: 3 int age; 4 public: 5 person(int a){ 6 this->age=a; 7 } 8 inline bool operator == (const person &ps) const; 9 };
實現方式如下:
1 inline bool person::operator==(const person &ps) const 2 { 3 if (this->age==ps.age) 4 return true; 5 return false; 6 }
調用方式如下:
1 #include 2 using namespace std; 3 int main() 4 { 5 person p1(10); 6 person p2(20); 7 if(p1==p2) cout<<”the age is equal!”< return 0; 8 }
這里,因為operator ==是class person的一個成員函數,所以對象p1,p2都可以調用該函數,上面的if語句中,相當於p1調用函數==,把p2作為該函數的一個參數傳遞給該函數,從而實現了兩個對象的比較。
B:操作符重載實現為非類成員函數(全局函數)
對於全局重載操作符,代表左操作數的參數必須被顯式指定。例如:
1 class person 2 { 3 public: 4 int age; 5 public: 6 }; 7 8 bool operator==(person const &p1 ,person const & p2) 9 //滿足要求,做操作數的類型被顯示指定 10 { 11 if(p1.age==p2.age) 12 return true; 13 return false; 14 }
調用方式如下:
1 int main() 2 { 3 person rose; 4 person jack; 5 rose.age=18; 6 jack.age=23; 7 if(rose==jack) 8 cout<<"ok"< return 0; 9 }
C:如何決定把一個操作符重載為類成員函數還是全局名字空間的成員呢?
①如果一個重載操作符是類成員,那么只有當與他一起使用的左操作數是該類的對象時,該操作符才會被調用。如果該操作符的左操作數必須是其他的類型,則操作符必須被重載為全局名字空間的成員。
②C++要求賦值=,下標[],調用(), 和成員指向-> 操作符必須被定義為類成員操作符。任何把這些操作符定義為名字空間成員的定義都會被標記為編譯時刻錯誤。
③如果有一個操作數是類類型如string類的情形那么對於對稱操作符比如等於操作符最好定義為全局名字空間成員。
以下是C++ operator重載的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include <iostream>
using
namespace
std;
class
A
{
public
:
A(
double
_data = 0.0):data(_data){}
A& operator = (
const
A& rhs)
{
data = rhs.data;
return
*
this
;
}
friend
A operator + (
const
A& lhs,
const
A& rhs);
friend
A operator - (
const
A& lhs,
const
A& rhs);
friend
A operator * (
const
A& lhs,
const
A& rhs);
friend
A operator + (
const
A& lhs,
double
rhs);
friend
A operator + (
double
lhs,
const
A& rhs);
friend
A operator * (
const
A& lhs,
double
rhs);
friend
A operator * (
double
lhs,
const
A& rhs);
friend
A operator - (
const
A& lhs,
double
rhs);
friend
A operator - (
double
lhs,
const
A& rhs);
friend
ostream& operator << (ostream& fout,A& a);
// A& operator += (const A& rhs);
// A& operator -= (const A& rhs);
// A& operator *= (const A& rhs);
private
:
double
data;
};
A operator + (
const
A& lhs,
const
A& rhs)
{
A res(0);
res.data = lhs.data + rhs.data;
return
res;
}
A operator - (
const
A& lhs,
const
A& rhs)
{
A res(0);
res.data = lhs.data - rhs.data;
return
res;
}
A operator * (
const
A& lhs,
const
A& rhs)
{
A res(0);
res.data = lhs.data * rhs.data;
return
res;
}
A operator + (
const
A& lhs,
double
rhs)
{
A res(0);
res.data = lhs.data + rhs;
return
res;
}
A operator + (
double
lhs,
const
A& rhs)
{
A res(0);
res.data = lhs + rhs.data;
return
res;
}
A operator * (
const
A& lhs,
double
rhs)
{
A res(0);
res.data = lhs.data * rhs;
return
res;
}
A operator * (
double
lhs,
const
A& rhs)
{
A res(0);
res.data = lhs * rhs.data;
return
res;
}
A operator - (
const
A& lhs,
double
rhs)
{
A res(0);
res.data = lhs.data - rhs;
return
res;
}
A operator - (
double
lhs,
const
A& rhs)
{
A res(0);
res.data = lhs - rhs.data;
return
res;
}
ostream& operator << (ostream& fout,A& a)
{
fout << a.data ;
return
fout;
}
int
main(
int
argc,
char
* argv[])
{
A a(2.3);
A b(1.2);
A d(3.4);
A c;
c = a + b + d;
c=a+b;
c=a+1.0;
c=a-b;
c=a-1.0;
c=a*b;
c=a*1.0;
cout << c << endl;
c=1.0+2.0*a*a-3.0*a*b;
cout << c << endl;
return
0;
}
|