C++語言之重載運算符()/[]/++/->等運算符
文章鏈接:http://blog.csdn.net/qq_16628781/article/details/72629722
知識點
- 重載()運算符;
- 重載[]運算符;
- 重載++和->運算符;
- 新名詞記錄{operator}
概述
operator操作符一文包括兩種用法,一種是operator overloading(操作符重載),一種是operator casting(操作隱式轉換)。
這是C++和pascal擴展運算符功能的方法,雖然樣子古怪,但也可以理解:一方面要使運算符的使用方法與其原來一致,另一方面擴展其功能只能通過函數的方式(c++中,“功能”都是由函數實現的)。
爲什麼使用操作符重載?
對於系統的所有操作符,一般情況下,只支持基本數據類型和標準庫中提供的class,對於用戶自己定義的class,如果想支持基本操作,比如比較大小,判斷是否相等,則需要用戶自己來定義關於這個操作符的具體實現。比如,這個預算符,我想用某一個字段進行比價判斷是否相等,這就需要程序員重新賦予這個運算符的具體操作了。
重載()運算符
class Distance
{
//私有成員
private:
int feet;
int inches;
char dis[10];
public:
// 所需的構造函數
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// 這是創建一個可以傳遞任意數目參數的運算符函數。
/**
* 重載了括號(),
* 傳入4個參數,分別進行初始化,最後將新的對象返回出去
*/
Distance operator ()(int a, int b, int c, char d[10])
{
Distance D;
// 進行隨機計算
D.feet = a + c + 10;
D.inches = b + c + 100 ;
strcpy(D.dis, d);
//返回新的Distance對象
return D;
}
//打印距離的方法
void displayDistance()
{
cout << "feet: " << feet << " inches:" << inches << ", dis:" << dis << endl;
}
};
在上面的代碼中,我們看到**distance operator () (int a, int b, int c, char d[10])**方法,這裏是重載了"()"操作符,需要傳入4個參數,重新定義一個distance類,並且利用傳入的參數初始化此類的成員變量,最後返回出去。當然,這裏必須要用一個distance類變量才能夠調用此方法,然後利用一個新的變量來接收返回值。
具體的測試代碼如下所示:
void kuohaoTest(){
Distance D1(111, 130), D2;
cout << "first distance : ";
D1.displayDistance();
//調用distance變量的()方法,需要對應參數的個數
D2 = D1(10, 10, 10, "765");
cout << "second distance :";
D2.displayDistance();
}
運行結果如下圖所示:
重載 []
const int SIZE = 10;
class safearray
{
private:
int arr[SIZE];
public:
safearray()
{
register int i;
for(i = 0; i < SIZE; i++)
{
arr[i] = i;
}
}
int & operator[](int i)
{
if( i > SIZE )
{
//當傳入的index大於數組的長度,則返回第一個元素
return arr[0];
}
return arr[i];
}
};
在上面中,重載了[],裏面做了一個判斷,如果傳入的i超過了數組的長度,那麼就返回數組的第一個數據,保證了訪問數組時,不會出現數組越界的情況。
下面是測試代碼
/**
* 重載方括號,保證數組不會越界
*/
void fangkuohaoTest(){
safearray A;
cout << "A[2] 的值爲 : " << A[2] <<endl;
cout << "A[5] 的值爲 : " << A[5]<<endl;
cout << "A[12] 的值爲 : " << A[12]<<endl;
}
在第三個裏面,我們需要訪問數組的第13個數據,第13個數據顯然是不存在的,因爲總共只有10個數據。因爲判斷到超過了數組的長度,所以返回來的必然是第一個數據。
運行結果如下圖所示:
重載++ / ->
class obj {
static int i, j;
public:
void f() const { cout << "f: " << i++ << endl; }
void g() const { cout << "g: " << j++ << endl; }
};
// 靜態成員定義
int obj::i = 1;
int obj::j = 12;
// 爲上面的類實現一個容器
class objContainer
{
vector<obj*> a;
public:
void add(obj* obj)
{
a.push_back(obj); //調用向量的標準方法
}
friend class smartPointer;
};
// 實現智能指針,用於訪問類 Obj 的成員
class smartPointer {
objContainer oc;
int index;
public:
smartPointer(objContainer &objc)
{
oc = objc;
index = 0;
}
// 返回值表示列表結束
bool operator ++ () // 前增量,只有一個括號
{
if(index >= oc.a.size()) return false;
if(oc.a[++index] == 0) return false;//index加1
return true;
}
bool operator ++ (int) // 後增量,括號裏面有一個int類型
{
return operator++();
}
// 重載運算符 ->
obj* operator -> () const
{
if(!oc.a[index])
{
cout << "Zero value";
return (obj*)0;
}
//不爲空,指向oc.a向量裏面的obj類的實例
return oc.a[index];
}
};
void pointerTest(){
const int sz = 10;
obj o[sz];
objContainer oc;
for(int i = 0; i < sz; i++)
{
oc.add(&o[i]);
}
smartPointer sp(oc); // 創建一個迭代器
do {
sp->f(); // 智能指針調用
sp->g();
} while(sp++);
}
在上面的smartPointer類,重寫了++和->兩個方法,都是做了防止越界的判斷。在pointerTest()方法裏面,objContainer變量中先放入了10個obj變量,然後依次調出來,打印語句。結果如下圖所示:
總結
上面注意說明了利用operator關鍵字進行一些操作符的重新定義,使之更加滿足自己業務的需要。
只有C++預定義的操作符集中的操作符纔可以被重載,例如+,-,*,/,%,^…等等,但是都不改變它們之間的操作個數和優先級;以及一些內置類型的操作符不能改變,比如int類型的+。
以上就是所有內容,如有任何問題,請及時與我聯繫,謝謝。