1、運算符重載是為了對用戶自定義數據類型的數據的操作與內定義的數據類型的數據的操作形式一致。不能重載的5個運算符:*成員指針訪問運算符;::域運算符;sizeof長度運算符;?:條件運算符;.成員訪問符。
運算重載的三種方式:普通函數,友元函數,類成員函數。
當重載為成員函數時,雙目運算符僅有一個參數。對單目運算符,重載為成員函數時,不能再顯式說明參數。重載為成員函數時,總時隱含了一個參數,該參數是this指針。this指針是指向調用該成員函數對象的指針。
運算符重載函數還可以為友元函數。當重載友元函數時,將沒有隱含的參數this指針。這樣,對雙目運算符,友元函數有2個參數,對單目運算符,友元函數有一個參數。但是,有些運行符不能重載為友元函數,它們是:=,(),[]和->。
原因:有人說是因為
C++規定賦值運算符“=”只能重載為類的非靜態成員函數,而不可以重載為類的友元函數。
不能重載為類的靜態成員應該比較容易理解,因為靜態成員函數是屬於整個類的,不是屬於某個對象的,它只能去操作類靜態數據成員。而賦值運算符“=”是基於對象操作的。
當把賦值運算符重載為類的友員函數,在程序中執行類對象的賦值語句時,程序就會出現兩種矛盾的選擇。
(1)因為它認為類中並沒有重載賦值運算符的成員函數,所以它根據C++的規則,會去調用相應的構造函數。
(2)但是在全局里,我們已經重載了參數類型為此類類型的賦值運算符函數,而這賦值語句剛好和這函數匹配上了,根據C++的規則,也會去調用這函數。
程序是不允許有矛盾不確定選擇的,所以當賦值運算符重載為類的友元函數時,編譯器就會提示錯誤。
2、流運算符為什么不能重載為成員函數,只能用友元函數重載,cout<<obj;
cout << f1 << f2;
//用重載運算符表示,只能通過友員來實現,如果要用成員函數,則會有cout.operator<<(const F& f),所以這是不可能的.因此只能用友員來實現,operator<<(cout,f) 而cout是ostream型的,因此有以下標准格式.注意不能加const,因為cout是要改變的,會改變里的緩沖成員.
friend ostream& operator<<( ostream& cout, constF&) //輸出運算符的標准重載格式.
friend istream& operator>>(istream& is, F& f){ } //輸入運算符重載標准格式
#include <iostream>
using namespace std;
class F{
int n;
int d;
public :
F(int n=0, int d=1):n(n),d(d){}
friend ostream& operator<<(ostream& os, const F& f){
os << '[' << f.n << '/' << f.d <<']';
return os;
}
F operator*(const F& o) {
return F(n*o.n,d*o.d);
}
friend F operator/(const F& f1,const F& f2){
return F(f1.n/f2.d,f1.d/f2.n);
}
friend istream& operator>>(istream& is, F& f){
char ch;
is >> f.n >> ch >> f.d;
return is;
}
};
int main()
{
F f1(3,5),f2(11,7),f;
cout << f1 << '*' << f2 << '=' << f1*f2 << endl;
cout << f1 << '/' << f2 << '=' << f1/f2 << endl;
cout << "Input 2 fractions :";
cin >> f1 >> f2;
cout <<"f1=" << f1 << endl;
cout << "f2=" << f2 << endl;
}
3、在類成員函數中重載運算符是不允許返回引用的,會出現“返回局部變量的地址”警告
4、把后++,后--當作雙目運算符,第二個操作數是整形
單目運算符重載
-友元函數形式:返回類型 operatorX(形參)
使用:X obj ---> operatorX(obj);
-成員函數形式 盡量用成員:返回類型 operatorX(/*無形參*/)
使用: X obj ---> obj.operator();
#include <iostream>
using namespace std;
class A{
int data;
public :
A(int d=0):data(d){}
friend ostream& operator<<(ostream& os,const A& a){
os << a.data;
return os;
}
friend istream& operator>>(istream& is,A& a){
is >> a.data;
return is;
}
friend A& operator++(A& a){
a.data += 10;
return a;
}
A& operator--(){
data -= 10;
return *this;
}
friend A/* 不能用引用 */ operator++(A& a,int){
A old(a);
a.data += 1;
return old;
}
A /* 不能用引用 */ operator--(int){
A old(*this);
data -= 1;
return old;
}
};
int main()
{
A a1(50),a2(100);
cout << "a1=" <<a1 << endl;
cout << "a2=" <<a2 << endl;
cout << "++a1=" << ++a1 << endl;
cout << "--a1=" << --a1 << endl;
cout << "a1++=" << a1++ << endl;
cout << "a1=" <<a1 << endl;
cout << "a2--=" << a2-- << endl;
cout << "a2=" <<a2 << endl;
}
5、強制類型轉換:類型(數據) --> (不必寫返回類型,因為始終與后面的類 型是相同的) operator類型(無形參) 只能寫成成員函數,不能是友員.
#include<iostream>
using namespacestd;
classA{
intdata;
public:
A(intd=0):data(d){}
operator int(){
returndata;
}
operator bool(){
returndata!=0;
}
operator char(){
return(char)data;
}
};
intmain()
{
A a1(65),a2(200);
cout << "a1="<< (char)a1 << endl;
intd=a2;
if(a2)
cout << "good"<< endl;
}