C 運算子過載

2022-04-07 07:37:43 字數 4557 閱讀 4344

個人筆記,僅供複習

1.1 背景:運算子只能用於基本資料型別進行運算,不能用於物件之間。為了滿足物件之間可以通過運算子進行運算。

1.2 概念:對已有的運算子(c++中預定義的運算子)賦予多重含義,使

同一運算子作用於不同型別的資料時導致不同的行為

1.3 目的:擴充套件c++中提供的運算子的適用範圍,使之能作用於物件。

1.4 形式:

返回值型別  operator 運算子 (形參表)

{...    ...

1.5 運算子過載例項:

#includeusing namespace std;

class complex

complex operator - (const complex &c);

};complex operator + (const complex &a ,const complex &b)

complex complex::operator -(const complex &c)

int main()

其中 c = a+b;等價於 c = operator + (a,b);

a-b;       等價於a.operator-(b);

注:過載為成員函式時,引數個數為運算子數目減一;

過載為普通函式時,引數個數為運算子數目。

2.1 背景:有時希望賦值運算子兩邊的型別可以不匹配,比如,把乙個int型別變數賦值給乙個complex物件,或把乙個char * 型別的字串賦值給乙個字串物件,此時就需要過載運算子「=」。

注:賦值運算子「=」只能過載為成員函式。

2.2 **例項:

#include#includeusing namespace std;

class string

const char * c_str()

string & operator = (const char * s);

~string( )

};string & string::operator =(const char*s)

int main()

2.3 細節處理:s1 = "this",s2="that";

s1 = s2;

string & operator = (const string & s)
另外如果令s=s,還是會出錯。

string & operator = (const string & s)
2.4 對返回值型別的討論:對運算子進行過載的時候,好的風格是應該盡量保留運算子原本的特性。

考慮 a = b = c 和 (a = b) = c;

分別等價於: a.operator = (b.operator(c)) 和 (a.operator=(b)).operator=(c).

3.1 背景:一般情況下,將運算子過載為類的成員函式,是較好的選擇。但有時,過載為成員函式不能滿足使用要求,過載為普通函式,又不能訪問類的私有成員,所以需要將運算子過載為友元。

4.1 編寫乙個類,使之能如下使用:

int main()
4.2 **例項:

#include#includeusing namespace std;

class carray

carray():p(null),size(0)

~carray()

int & operator(int i);

carray & operator = (const carray &);

carray(const carray &);

};void carray::push_back(int i)

else

p = new int[1];

p[size++] = i;

}int & carray::operator(int i)

carray & carray::operator = (const carray & c)

if(size < c.size)

size = c.size;

memcpy(p,c.p,sizeof(int)*size);

return *this;

}carray::carray(const carray & c)

p = new int[c.size];

memcpy(p,c.p,sizeof(int)*c.size);

size = c.size;

}int main()

5.流插入運算子和流提取運算子的過載5.1 概念:cout << 5 << 「this」;本質上的函式呼叫是cout.operator<<(5).operator<<(「this」);

5.2 **例項:假定c是complex複數類的物件,現在希望寫「cout << c;」,就能以

「a+bi」的形式

輸出c的值,寫「cin>>c;"就能從鍵盤接受「

a+bi」形式的輸入

,並且使得c

.real = a,c.imag = b。

#include#include#includeusing namespace std;

class complex

friend ostream & operator << (ostream &o, const complex & a);

friend istream & operator >> (istream &is,complex & c);

};ostream & operator << (ostream &o, const complex & a)

int main()

注:由於istream類和ostream類都已經定義好,所以《和》運算子都只能過載為全域性函式,為了防止全域性函式無法訪問私有成員,可以將其宣告為友元。

6.1 **例項:

#include using namespace std;

class complex

; operator double ()

//過載強制型別轉換運算子 double

};int main()

上面倒數第三行可以看出如果對型別轉換運算子進行了過載,那麼編譯器會自動的對物件進行合理的強制型別轉換。

7.1 概念:自增自減運算子有前置和後置之分,為了區分所過載的是前置運算子還是後置運算子,c++規定:

過載為成員函式:

t & operator++();

t & operator--();

過載為全域性函式:

t1 & operator++(t2);

t1 & operator—(t2);

過載為成員函式:

t operator++(int);

t operator--(int);

過載為全域性函式:

t1 operator++(t2,int );

t1 operator—( t2,int);

注:在沒有後置運算子過載而有前置運算子過載的情況下,在vs中,obj++也呼叫前置過載,而dev中obj++則出錯。

7.2 **例項:

#includeusing namespace std;

class cdemo

cdemo & operator ++ ();

cdemo operator ++(int);

friend cdemo & operator --(cdemo &);

friend cdemo operator --(cdemo &,int);

operator int ()

};cdemo &cdemo::operator ++ ( )//++s即為s.operator++()

cdemo cdemo::operator++( int k )

// s++即為: s.operator++(0);

cdemo & operator -- (cdemo & a)

cdemo operator -- (cdemo & a,int k)

int main()

其中,當自增運算子前置時,要求返回乙個改變後的物件,所以要用該物件的引用,返回改變後的物件。當自增運算子後置時,要求改變當前物件的值並返回改變之前的值,所以要將該物件臨時儲存,改變後返回臨時物件。

C 運算子過載 過載特殊運算子

賦值運算子用於同類物件間的相互賦值。賦值運算子只能被過載為類的非靜態成員函式,不能過載為友元函式和普通函式。對於使用者自定義的類而言,如果沒有過載賦值運算子,那麼c 編譯器會為該類提供乙個預設的過載賦值運算子成員函式。預設賦值運算子的工作方式是按位對拷,將等到右邊物件的非靜態成員拷貝給等號左邊的物件...

C 運算子過載賦值運算子

自定義類的賦值運算子過載函式的作用與內建賦值運算子的作用類似,但是要要注意的是,它與拷貝建構函式與析構函式一樣,要注意深拷貝淺拷貝的問題,在沒有深拷貝淺拷貝的情況下,如果沒有指定預設的賦值運算子過載函式,那麼系統將會自動提供乙個賦值運算子過載函式。賦值運算子過載函式的定義與其它運算子過載函式的定義是...

C 運算子過載轉換運算子

為什麼需要轉換運算子?大家知道對於內建型別的資料我們可以通過強制轉換符的使用來轉換資料,例如 int 2.1f 自定義類也是型別,那麼自定義類的物件在很多情況下也需要支援此操作,c 提供了轉換運算子過載函式 它使得自定義類物件的強轉換成為可能。轉換運算子的生命方式比較特別,方法如下 operator...