C++ 運算符重載
什麼是運算符的重載?
運算符與類結合,產生新的含義。
爲什麼要引入運算符重載?
作用:爲了實現類的多態性(多態是指一個函數名有多種含義)
怎麼實現運算符的重載?
方式:類的成員函數或友元函數(類外的普通函數)
規則:不能重載的運算符有 . 和 .* 和 ?: 和 :: 和 sizeof
友元函數和成員函數的使用場合:一般情況下,建議一元運算符使用成員函數,二元運算符使用友元函數
1、運算符的操作需要修改類對象的狀態,則使用成員函數。如需要做左值操作數的運算符(如=,+=,++)
2、運算時,有數和對象的混合運算時,必須使用友元
3、二元運算符中,第一個操作數爲非對象時,必須使用友元函數。如輸入輸出運算符<<和>>
具體規則如下:
運算符 |
建議使用 |
所有一元運算符 |
成員函數 |
= ( ) [ ] -> |
必須是成員函數 |
+= -= /= *= ^= &= != %= >>= <<= , 似乎帶等號的都在這裏了. |
成員函數 |
所有其它二元運算符, 例如: –,+,*,/ |
友元函數 |
<< >> |
必須是友元函數 |
2. 參數和返回值
當參數不會被改變,一般按const引用來傳遞(若是使用成員函數重載,函數也爲const).
對於返回數值的決定:
1) 如果返回值可能出現在=號左邊, 則只能作爲左值, 返回非const引用。
2) 如果返回值只能出現在=號右邊, 則只需作爲右值, 返回const型引用或者const型值。
3) 如果返回值既可能出現在=號左邊或者右邊, 則其返回值須作爲左值, 返回非const引用。
運算符重載舉例:
+和 -運算符的重載:
1. class Point
2. {
3. private:
4. int x;
5. public:
6. Point(int x1)
7. { x=x1;}
8. Point(Point& p)
9. { x=p.x;}
10. const Point operator+(const Point& p);//使用成員函數重載加號運算符
11. friend const Point operator-(const Point& p1,const Point& p2);//使用友元函數重載減號運算符
12. };
13.
14. const Point Point::operator+(const Point& p)
15. {
16. return Point(x+p.x);
17. }
18.
19. Point const operator-(const Point& p1,const Point& p2)
20. {
21. return Point(p1.x-p2.x);
22. }
class Point
{
private:
int x;
public:
Point(int x1)
{ x=x1;}
Point(Point& p)
{ x=p.x;}
const Point operator+(const Point& p);//使用成員函數重載加號運算符
friend const Point operator-(const Point& p1,const Point& p2);//使用友元函數重載減號運算符
};
const Point Point::operator+(const Point& p)
{
return Point(x+p.x);
}
Point const operator-(const Point& p1,const Point& p2)
{
return Point(p1.x-p2.x);
}
調用:
1. Point a(1);
2. Point b(2);
3. a+b; //正確,調用成員函數
4. a-b; //正確,調用友元函數
5. a+1; //正確,先調用類型轉換函數,把1變成對象,之後調用成員函數
6. a-1; //正確,先調用類型轉換函數,把1變成對象,之後調用友元函數
7. 1+a; //錯誤,調用成員函數時,第一個操作數必須是對象,因爲第一個操作數還有調用成員函數的功能
8. 1-a; //正確,先類型轉換 後調用友元函數
Point a(1);
Point b(2);
a+b; //正確,調用成員函數
a-b; //正確,調用友元函數
a+1; //正確,先調用類型轉換函數,把1變成對象,之後調用成員函數
a-1; //正確,先調用類型轉換函數,把1變成對象,之後調用友元函數
1+a; //錯誤,調用成員函數時,第一個操作數必須是對象,因爲第一個操作數還有調用成員函數的功能
1-a; //正確,先類型轉換 後調用友元函數
總結:
1、由於+ -都是出現在=號的右邊,如c=a+b,即會返回一個右值,可以返回const型值
2、後幾個表達式討論的就是,數和對象混合運算符的情況,一般出現這種情況,常使用友元函數
3、雙目運算符的重載:
重載運算符函數名:operator@(參數表)
隱式調用形式:obj1+obj2
顯式調用形式:obj1.operator+(OBJ obj2)---成員函數
operator+(OBJ obj1,OBJ obj2)---友元函數
執行時,隱式調用形式和顯式調用形式都會調用函數operator+()
++和--運算符的重載:
1. class Point
2. {
3. private:
4. int x;
5. public:
6. Point(int x1)
7. { x=x1;}
8. Point operator++();//成員函數定義自增
9. const Point operator++(int x); //後綴可以返回一個const類型的值
10. friend Point operator--(Point& p);//友元函數定義--
11. friend const Point operator--(Point& p,int x);//後綴可以返回一個const類型的值
12. };
13.
14. Point Point::operator++()//++obj
15. {
16. x++;
17. return *this;
18. }
19. const Point Point::operator++(int x)//obj++
20. {
21. Point temp = *this;
22. this->x++;
23. return temp;
24. }
25. Point operator--(Point& p)//--obj
26. {
27. p.x--;
28. return p;
29. //前綴形式(--obj)重載的時候沒有虛參,通過引用返回*this 或 自身引用,也就是返回變化之後的數值
30. }
31. const Point operator--(Point& p,int x)//obj--
32. {
33. Point temp = p;
34. p.x--;
35. return temp;
36. // 後綴形式obj--重載的時候有一個int類型的虛參, 返回原狀態的拷貝
37. }
class Point
{
private:
int x;
public:
Point(int x1)
{ x=x1;}
Point operator++();//成員函數定義自增
const Point operator++(int x); //後綴可以返回一個const類型的值
friend Point operator--(Point& p);//友元函數定義--
friend const Point operator--(Point& p,int x);//後綴可以返回一個const類型的值
};
Point Point::operator++()//++obj
{
x++;
return *this;
}
const Point Point::operator++(int x)//obj++
{
Point temp = *this;
this->x++;
return temp;
}
Point operator--(Point& p)//--obj
{
p.x--;
return p;
//前綴形式(--obj)重載的時候沒有虛參,通過引用返回*this 或 自身引用,也就是返回變化之後的數值
}
const Point operator--(Point& p,int x)//obj--
{
Point temp = p;
p.x--;
return temp;
// 後綴形式obj--重載的時候有一個int類型的虛參, 返回原狀態的拷貝
}
函數調用:
1. <PRE class=cpp name="code">Point a(1);
2. Point b(2);
3. a++;//隱式調用成員函數operator++(0),後綴表達式
4. ++a;//隱式調用成員函數operator++(),前綴表達式
5. b--;//隱式調用友元函數operator--(0),後綴表達式
6. --b;//隱式調用友元函數operator--(),前綴表達式
7. cout<<a.operator ++(2);//顯式調用成員函數operator ++(2),後綴表達式
8. cout<<a.operator ++();//顯式調用成員函數operator ++(),前綴表達式
9. cout<<operator --(b,2);//顯式調用友元函數operator --(2),後綴表達式
10. cout<<operator --(b);//顯式調用友元函數operator --(),前綴表達式 </PRE>
[cpp] view plaincopyprint?
1.Point a(1);
2.Point b(2);
3.a++;//隱式調用成員函數operator++(0),後綴表達式
4.++a;//隱式調用成員函數operator++(),前綴表達式
5.b--;//隱式調用友元函數operator--(0),後綴表達式
6.--b;//隱式調用友元函數operator--(),前綴表達式
7.cout<<a.operator ++(2);//顯式調用成員函數operator ++(2),後綴表達式
8.cout<<a.operator ++();//顯式調用成員函數operator ++(),前綴表達式
9.cout<<operator --(b,2);//顯式調用友元函數operator --(2),後綴表達式