C++ 運算符重載 ++ --

1.基本知識:
  • 左值(L-value):左值可以出現在賦值語句的左邊或右邊;
    • 左值(L-value) 的L 應該被理解爲Location ,表示可尋址的,有確定地址的
  • 右值(R-value): 右值只能出現在賦值語句的右邊
    • 右值(R-value) 的R 應該被理解爲Read ;
  • 簡單來說, 有確定地址,可取地址的是左值;否則就是右值;
2. C++規定運算符重載必須針對類的對象,即重載時至少有一個參數代表對象(類型如A、const A、A&、const A&、volatile A等) 。
3.C++用operator加運算符進行運算符重載。對於運算符實例成員函數,this隱含參數代表第一個操作數對象;
4.根據能否重載及重載函數的類型,運算符分爲:
  • 不能重載的:sizeof 、. 、 .* 、 :: 、 ? :
  • 只能重載爲實例函數成員的:=、–>、( )、[ ]
  • 不能重載爲實例函數成員的:new、delete
  • 其他運算符:都不能重載爲靜態函數成員,但可以重載爲實例函數成員和普通函數(非成員函數)。
class A;
int operator=(int, A&); //錯誤,不能重載爲普通函數
A& operator +=(A&,A&);//A*和A[ ]參數不代表對象
class A{
	friend int operator=(int,A&); //錯誤,不存在operator=
	static int operator( )(A&,int); //錯誤,不能爲靜態成員
	static int operator+(A&,int); //錯誤,不能爲靜態成員
	friend A& operator += (A&,A&); //正確
	A& operator ++( ); //正確:隱含參數this代表一個對象
};
5. 若運算符爲傳統左值運算符,則重載後運算符函數最好返回非只讀有址引用類型(傳統左值)。當運算符要求第一個參數爲傳統左值時,不能使用const說明第一個參數(如this),例如++、–、=、+=等的第一個參數。
6. 若運算結果爲傳統右值,返回類型最好帶有const;
示例代碼
class A{
int x, y;
public:
A(int x, int y) { A::x=x; A::y=y; }
A &operator=(const A&m) //返回傳統左值,返回值可被賦值
{ x=m.x; y=m.y; return *this;}; //有址引用當前對象,可繼續對其賦值
	friend const A operator-(const A&); //參數及返回值爲傳統右值,不可改
	friend const A operator+(const A&, const A&); //同上
	} a(2,3), b(4,5), c(1, 9);
	const A operator -(const A&a){ return A(-a.x, -a.y); } //返回傳統右值
	const A operator +(const A&x, const A&y){ //返回傳統右值
	return A(x.x+y.x, x.y+y.y); //A(x.x+y.x, x.y+y.y)爲類A的常量
}
void main(void){ (c=a+b)=b+b /*c=a+b, c=b+b*/; c= -b; } 
運算符函數的參數
  • 重載函數種類不同,參數表列出的參數個數也不同
    • 重載爲重載爲實例成員:參數個數=運算符目數 - 1 (即this指 針)普通函數:參數個數=運算符目數;
    • 重載爲實例成員:參數個數=運算符目數 - 1 (即this指針);
    • 重載爲靜態成員:參數個數 = 運算符目數(沒有this指針);
示例代碼
#include <iostream>
using namespace std;

class A
{
    int a;
    friend A &operator--(A &);//無this,僅一個參數,前置  
    //有多個運算符 "++" 與這些操作數匹配: -- 函數 "operator++(A &)" -- 函數 "A::operator++()" -- 操作數類型爲:  ++ A
    friend A operator--(A &, int); //兩個參數,後置運算
public:
    int get() { return a; }
    A &operator++();   //只有this參數,前置
    A operator++(int); //包括this共兩個參數,後置
    A(int x) { a = x; }
};
A &operator--(A &x)
{
    x.a--;
    return x;
}
A operator--(A &x, int)
{ //後置
    return A(x.a--);
}
A &A::operator++()
{//前置 ++ 返回引用對象(左值)
//前置運算結果的左值等於當前對象,且返回的引用對象不能引用局部對象
//故必須return *this 返回對當前對象的引用
    a++;
    return *this;
}
A A::operator++(int)
{ //後置
    return A(a++);
}
int main()
{
    A a(5);
    cout << " " << (--a).get() << endl;
    cout << " " << (++a).get() << endl;
    cout << " " << (a--).get() << endl;
    cout << " " << (a++).get() << endl;
    return 0;
}
輸出
 4
 5
 5
 4
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章