一般說來,單目運算子最好被重載為成員;對雙目運算子最好被重載為友元函數,雙目運算子多載為友元函數比重載為成員函數更方便.
運算子多載實際是一個函數,所以運算子的重載實際上是函數的重載。編譯器對運算子多載的選擇,遵循著函數重載的選擇原則。當遇到不很明顯的運算時,編譯器將去尋找參數相匹配的運算子函數。
運算子多載的作用:
運算子多載允許C/C++的運算子在使用者定義型別(類)上擁有一個使用者定義的意義。重載的運算子是函數調用的文法修飾:
- class Fred
- Fred add(Fred, Fred);
- Fred operator+ (Fred, Fred);
功能相同,只是沖在'+'使得功能更加的直觀.
可以用作重載的運算子:
算術運算子:+,-,*,/,%,++,--;
位操作運算子:&,|,~,^,<<,>>
邏輯運算子:!,&&,||;
比較子:<,>,>=,<=,==,!=;
賦值運算子:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;
其他運算子:[],(),->,,(逗號運算子),new,delete,new[],delete[],->*。
下列運算子不允許重載:
.,.*,::,?:
1. 重載為類的成員函數
- class complex
- complex operator +(const complex &c);
- inline complex complex::operator +(const complex &c)
- {
- return complex(real + c.real, imag + c.imag);
- }
程式中出現的運算式:
c1+c2
編譯器將給解釋為:
c1.operator+(c2)
其中,c1和c2是complex類的對象。operator+()是運算+的重載函數。
重載為成員函數時,不能再顯式說明參數。重載為成員函數時,總時隱含了一個參數,該參數是this指標。this指標是指向調用該成員函數對象的指標。
2. 重載為友元函數:
運算子多載函數還可以為友元函數。當重載友元函數時,將沒有隱含的參數this指標。這樣,對雙目運算子,友元函數有2個參數,對單目運算子,友元函數有一個參數。但是,有些運行符不能重載為友元函數,它們是:=,(),[]和->。
- friend complex operator +(const complex &c1, const complex &c2);
- complex operator +(const complex &c1, const complex &c2)
- {
- return complex(c1.real + c2.real, c1.imag + c2.imag);
- }
該程式的運行結果與上例相同。前面已講過,對又目運算子,重載為成員函數時,僅一個參數,另一個被隱含;重載為友元函數時,有兩個參數,沒有隱含參數。因此,程式中出現的 c1+c2
編譯器解釋為:
operator+(c1, c2)
3. 兩種重載形式的比較
一般說來,單目運算子最好被重載為成員;對雙目運算子最好被重載為友元函數,雙目運算子多載為友元函數比重載為成員函數更方便此,但是,有的雙目運算子還是重載為成員函數為好,例如,賦值運算子。因為,它如果被重載為友元函數,將會出現與賦值語義不一致的地方。
- counter operator ++();
- counter operator ++(int );
- counter counter::operator ++()
- {
- v++;
- return *this;
- }
- counter counter::operator ++(int)
- {
- counter t;
- t.v = v++;
- return t;
- }
4. 重載函數調用運算子
可以將函數調用運算子()看成是下標運算[]的擴充。函數調用運算子可以帶0個至多個參數。下面通過一個執行個體來熟悉函數調用運算子的重載.
- class F
- {
- double operator ()(double x, double y) const;
- };
- double F::operator ()(double x, double y) const
- {
- return (x+5)*y;
- }
- void main()
- {
- F f;
- cout<<f(1.5, 2.2)<<endl;
- }
5.重載輸出運算子 <<
下面是一個棧類的輸出 cout<<st;為輸出整個棧的元素
- friend ostream& operator<<(ostream &os ,const CSTAC &st);
- ostream& operator<<(ostream &os ,const CSTAC &st)//CSTAC::
- {
- if (st.count == 0)
- {
- os<<"the stack is empty!"<<endl;
- }
- for (int i=0; i<st.count; i++)
- {
- os<<st.p[i]<<" ";
- }
- os<<endl;
- return os;
- }
OVER