免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C++操作符重載手冊

ctycheer的日記

C++操作符重載手冊

http://hi.baidu.com/xiaoduo170/blog/item/9ae4cf51ae739110377abe16.html+ - * / % ^ & | ~ ! = > < += -= *= /= %= ^= &= |= >> << >>= <<= == != >= <= && || ++ -- ->* , -> [] () operator new operator new[] operator delete operator delete [] II.不能重載的操作符:: . .* ? : sizeof typeid new delete static_cast dynamic_cast const_cast reinterpret_cast III.基本規(guī)則1.一元操作符可以是不帶參數(shù)的成員函數(shù)[1]或帶一個參數(shù)的非成員函數(shù)[1]。2.二元操作符可以是帶一個參數(shù)的成員函數(shù)[1]或帶兩個參數(shù)的非成員函數(shù)[1]。3.operator=、operator[]、operator()、operator->只能定義為成員函數(shù)[1]。4.operator->的返回值必須是一個指針或能使用->的對象。5.重載 operator++ 和 operator-- 時帶一個 int 參數(shù)表示后綴,不帶參數(shù)表示前綴。6.除 operator new 和 operator delete 外,重載的操作符參數(shù)中至少要有一個非內(nèi)建數(shù)據(jù)類型。7.x@y 搜索范圍為:x 成員函數(shù)--> 全局函數(shù)/X所在名字空間中的函數(shù)/Y所在名字空間中的函數(shù)/X的友元函    數(shù)/Y的友元函數(shù)。8.重載的的操作符應(yīng)盡量模擬操作符對內(nèi)建類型的行為。二、使用重載I.操作符重載的一些建議     1.只將會改變第一個參數(shù)的值的操作符(如: +=)定義為成員函數(shù),而將返回一個新對象的操作符(如: +)定義為非成員函數(shù)(并使用 += 來實現(xiàn))。     2.只有非成員函數(shù)才能在左參數(shù)上實施性別轉(zhuǎn)換,如果需要進(jìn)行轉(zhuǎn)換則應(yīng)將操作符定義為非成員函數(shù)。     3.對一元操作符, 為避免隱式轉(zhuǎn)換最好將其重載為成員函數(shù)。     4.對二元操作符, 為能在左操作數(shù)上能進(jìn)行和右操作數(shù)一樣的隱式轉(zhuǎn)換, 最好將其重載為非成員函數(shù)。     5.為了遵照使用習(xí)慣,operator>>、operator<< 應(yīng)定義為非成員函數(shù)。     6.重載 operator[] 之類的操作符, 應(yīng)盡量提供 const 版本和非 const 版本。     7.關(guān)于將操作符定義為成員或非成員可參考以下建議:操作符 建 議  所有一元操作符  成員 = () [] ->  必須為成員 += -= /= *= ^= &= != %= >>= <<=  成員 其它二元操作符  非成員       8.如果默認(rèn)操作符已經(jīng)可以施用于你的型別上, 則應(yīng)盡量避免重載此操作符. 如 operator, 、operator&(取地址) 等等.II. 重載 operator new     1.為什么要重載 operator new ?[效率問題] 通常系統(tǒng)默認(rèn)提供的分配器速度極慢, 而且分配小型對象時空間浪費嚴(yán)重.[改變行為] 默認(rèn)的分配器失敗時會拋出異常, 或許你想改變這種行為.     2. operator new 的行為[區(qū)分三個不同的 new]      new 操作符(new 表達(dá)式, new operator, new expression): 通常我們調(diào)用 X * pX = new X 時使用的就是這個操作符, 它由語言內(nèi)建, 不能重載, 不能改變其行為. 它包括分配內(nèi)存的 operator new 和調(diào)用構(gòu)造函數(shù)的 placement new.     operator new :opeator new 是一個函數(shù), void * operator new(size_t size) . 它分配指定大小的內(nèi)存, 可以被重載, 可以添加額外的參數(shù), 但第一個參數(shù)必須為 size_t. operator new 除了被 new operator 調(diào)用外也可以直接被調(diào)用: void * rawMem = operator new(sizeof(X)).      placement new : placement new 在一塊指定的內(nèi)存上使用構(gòu)造函數(shù), 包含頭文件 <new> 之后也可以直接使用 placement new: X * pX = new (rawMem) X. [2]     與 new operator 類似, 對于 delete operator, 也存在 operator delete: void operator delete(void *), 析構(gòu)方法 pX->~X().[operator new 的錯誤處理]     默認(rèn)的 operator new 在內(nèi)存分配失敗時將會拋出 std::bad_alloc 異常; nothrow new [3] (X * pX = new (nothrow) X) 在內(nèi)存分配失敗時將會返回 0 . 這種行為可以通過設(shè)置 new-handler 來改變. new-handler 是一個回調(diào)函數(shù)指針, typedef void(*new_handler)(void). 通過 set_new_handler(new_handler) 函數(shù)設(shè)置回調(diào)句柄后, 如果分配內(nèi)存失敗, operator new 將會不斷的調(diào)用 new-handler 函數(shù), 直到找到足夠的內(nèi)存為止. 為了避免死循環(huán), new-handler 函數(shù)必須具備以下行為之一:     (1).找到可用的內(nèi)存.     (2).安裝其它的 new-handler 函數(shù).     (3).卸除 new-handler, 即 set_new_hanlder(0), 這樣下此循環(huán)將恢復(fù)默認(rèn)行為拋出異?;蚍祷?0.     (4).拋出異常.     (5).保存錯誤日志, 退出程序.     3.準(zhǔn)備重載 operator new     重載 operator new 時需要兼容默認(rèn)的 operator new 錯誤處理方式. 另外, C++ Standard 規(guī)定當(dāng)要求的內(nèi)存為 0 byte 時也應(yīng)該返回有效的內(nèi)存地址. 所以 operator new 的重載實現(xiàn)應(yīng)大致如下:void * ... operator new(size_t size ... ){     if(size == 0)         size = 1;      while(1)     {          ... // allocate memery         if(allocate sucessfull)             return ... // return the pointer.         new_handler curhandler = set_new_handler(0);         set_new_handler(curhandler); // get current new handler         if(curhandler == 0)             (*curhandler)();         else             throw std::bad_alloc();     }}     重載 operator delete 簡單許多, 只需注意 C++ Standard 要求刪除一個 NULL 是安全的即可.    4.重載 operator new     opeator new 的重載和其它操作符大不相同.首先, 即使你不重載, 默認(rèn)的 operator new 也可施用于你的自定義型別上(operator, 也具有此特性), 而其它操作符如果不進(jìn)行重載就無法使用. 其次, 其它重載其它操作符時參數(shù)個數(shù)都是固定的, 而 operator new 的參數(shù)個數(shù)是可以任意的, 只需要保證第一個參數(shù)為 size_t, 返回類型為 void * 即可, 而且其重載的參數(shù)類型也不必包含自定義類型. 更一般的說, operator new 的重載更像是一個函數(shù)的重載, 而不是一個操作符的重載. [★ 用不同的參數(shù)重載 operator new]     通過使用不同的參數(shù)類型, 可以重載 operator new, 例如 : void * operator new(size_t size, int x, int y, int z){     ...}X * pX = new (1, 2, 3) X;     你還可以為 operator new 的重載使用默認(rèn)值, 其原則和普通函數(shù)重載一樣, 只要不造成和已存在的形式發(fā)生沖突即可. 可能你已經(jīng)想到了, 你甚至還可以在 operator new 中使用不定參數(shù), 如果你真的需要的話. void * operator new(size_t size, int x, int y = 0, int z = 0){     ...}X * pX = new (10) X;Y * pY = new (10, 10) Y;Z * pZ = new (10, 10, 10) Z;...void * operator new(size_t size, ...)...     在全局空間中也可直接重載 void * operator new(size_t size) 函數(shù), 這將改變所有默認(rèn)的 new 操作符的行為, 不建議使用.[★ 重載 class 專屬的 operator new]     為某個 class 重載 operator new 時必須定義為類的靜態(tài)函數(shù)[4], 因為 operator new 會在類的對象被構(gòu)建出來之前調(diào)用. 即是說調(diào)用 operator new 的時候還不存在 this 指針, 因此重載的 operator new 必須為靜態(tài)的. 當(dāng)然在類中重載 operator new 也可以添加額外的參數(shù), 并可以使用默認(rèn)值.另外, 和普通函數(shù)一樣, operator new 也是可以繼承的. class X{...static void * operator new(size_t size); // ... (1)static void * operator new(size_t size, int); // ... (2)};class Y : public X{...};class Z : public X{...static void * operator new(size_t size); // ... (3)};X * pX1 = new X; // call (1)X * pX2 = ::new X; // call default operator newX * pX3 = new (0) X; // call (2)Y * pY1 = new Y; // call (1)Z * pZ1 = new Z; // call (3)Z * pZ2 = ::new Z; // call default operator newZ * pZ3 = X::new Z; // error, no way to call (1)Z * pZ4 = new (0) Z; // error, no way to call (2)     5.重載 operator delete     如果你重載了一個 operator new, 記得一定要在相同的范圍內(nèi)重載 operator delete. 因為你分配出來的內(nèi)存只有你自己才知道如何釋放. 如果你忘記了, 編譯器不會給你任何提示, 它將會使用默認(rèn)的 operator delete 來釋放內(nèi)存. 這種忘記的代價是慘重的, 你得時刻在寫下 operator new 的同時寫下 operator delete.      如果在類中使用 operator delete, 也必須將其聲明為靜態(tài)函數(shù). 因為調(diào)用 operator delete 時對象已經(jīng)被析構(gòu)掉了. operator delete 的重載可以有兩種形式:(1) void operator delete(void * mem)(2) void operator delete(void * mem, size_t size)     并且這兩種形式的 operator delete 可以同時存在, 當(dāng)調(diào)用 delete px 時, 如果 (1) 式存在的話將調(diào)用 (1) 式. 只有在 (1) 式不存在時才會調(diào)用 (2) 式. 對第 (2) 種形式的 operator delete, 如果用基類指針刪除派生類對象, 而基類的析構(gòu)函數(shù)沒有虛擬的時候, size 的值可能是錯誤的.三、重載參考- const Carrot operator+(const Carrot& lhs, const Carrot& rhs) {      Carrot result = lhs;     return result += rhs; } 【注】1. 如果可能, 應(yīng)考慮使用 operator+= 來實現(xiàn) operator+ .           2. operator+ 不能返回引用, 應(yīng)返回值類型.          3. 為了阻止形如 (a + b) = c 的調(diào)用, 應(yīng)將返回值聲明為 const .· const Carrot operator-(const Carrot& lhs, const Carrot& rhs)- const Carrot operator*(const Carrot& lhs, const Carrot& rhs) {      ... } 【注】1. operator* 還可以重載為提領(lǐng)操作符.· const Carrot operator/(const Carrot& lhs, const Carrot& rhs)· const Carrot operator%(const Carrot& lhs, const Carrot& rhs)· const Carrot operator^(const Carrot& lhs, const Carrot& rhs)- const Carrot operator&(const Carrot& lhs, const Carrot& rhs) {      ... } 【注】1. operator& 還可以重載為取地址操作符.· const Carrot operator|(const Carrot& lhs, const Carrot& rhs)- const Carrot Carrot::operator-() const {      Carrot result = (*this);     ... // chang the value to negative     return result; } 【注】1. 一元操作符, 取負(fù).· const Carrot Carrot::operator~() const· bool Carrot::operator!() const· bool operator>(const Carrot& lhs, const Carrot& rhs)· bool operator<(const Carrot& lhs, const Carrot& rhs)- Carrot& Carrot::operator=(const Carrot& rhs) {      if(this == &rhs)         return *this; // may be (*this) == rhs if needs.     Barley::operator=(rhs); // if Carrot derived from Barley      ... // assignments every memeber of Carrot.      return *this; } 【注】1. 為了實現(xiàn)形如 x=y=z=0 的串聯(lián)賦值操作, operator= 必須傳回 *this 的非常量引用.           2. 在賦值時應(yīng)注意檢查是否為自賦值 ( a = a ).- Carrot& Carrot::operator+=(const Carrot& rhs) {      ...      return *this; } 【注】1. C++ 允許 (x += 1) = 0 形式的賦值操作, operator+= 必須傳回 *this 的非常量引用.· Carrot& Carrot::operator-=(const Carrot& rhs)· Carrot& Carrot::operator*=(const Carrot& rhs)· Carrot& Carrot::operator/=(const Carrot& rhs)· Carrot& Carrot::operator%=(const Carrot& rhs)· Carrot& Carrot::operator^=(const Carrot& rhs)· Carrot& Carrot::operator&=(const Carrot& rhs)· Carrot& Carrot::operator|=(const Carrot& rhs)- istream& operator>>(istream& _IStr, Carrot& rhs) {      ...      return _IStr; } 【注】1. 為了遵照使用習(xí)慣(cin>>x 而不是 x>>cin), 對流操作的 operator>> 應(yīng)為非成員函數(shù).- ostream& operator<<(ostream& _OStr, const Carrot& rhs) {      ...      return _OStr; }- const Carrot operator>>(const Carrot& lhs, int rhs) {      Carrot result = lhs;     ...      return result; } 【注】1. 移位操作的重載方式.· const Carrot operator<<(const Carrot& lhs, int rhs)- Carrot& Carrot::operator>>=(int rhs) {      ...      return *this; } 【注】1. 移位操作.· Carrot& Carrot::operator<<=(int rhs)- bool operator==(const Carrot& lhs, const Carrot& rhs) {      ... }· bool operator!=(const Carrot& lhs, const Carrot& rhs)· bool operator>=(const Carrot& lhs, const Carrot& rhs)· bool operator<=(const Carrot& lhs, const Carrot& rhs)- bool operator&&(const Carrot& lhs, const Carrot& rhs) X {      ... } 【注】1. 基于以下原因, 你應(yīng)該避免重載 operator&& 和 operator|| :               (1). && 和 || 是一個邏輯操作符, 只對 bool 型別有才有明確的語意.                (2). 重載的 operator&& 和 operator|| 無法模擬操作符默認(rèn)的驟死式語義[5].               (3). 你無法保證重載后操作符的參數(shù)求值次序(C++ Stand 保證了默認(rèn)的 && 和 || 按從左到右求值).          2.自定義型別可以考慮提供到 bool 的轉(zhuǎn)型操作來支持此操作符.· bool operator||(const Carrot& lhs, const Carrot& rhs) X - Carrot& Carrot::operator++() {      (*this) += 1; // or other implement     return *this;} 【注】1. 前置操作(prefix): ++carrot- const Carrot Carrot::operator++(int) {      Carrot oldValue = *this;     ++(*this);     return oldValue;} 【注】1. 后置操作(postfix): carrot++ 調(diào)用時編譯器自動生成一個 0 作為參數(shù).          2. 為了禁止 carrot++++ 操作, 返回值應(yīng)為 const.          3. 從實現(xiàn)和參數(shù)可以看出,后置操作的效率遠(yuǎn)遠(yuǎn)低于前置操作, 所以如非必要盡量使用前置操作.          4. 為了保證遞增行為一致, 并便于維護(hù)后置操作最好使用前置操作來完成遞增行為.· Carrot& Carrot::operator--()· const Carrot Carrot::operator--(int)- const Carrot operator,(const Carrot& lhs, const Carrot& rhs) X {      ...} 【注】1. 基于以下原因, 你應(yīng)該避免重載 operator, :               (1). 即使沒有重載, 默認(rèn),號操作符也可以施用于自定義型別上.                (2). C++ 保證 , 操作符的求值是從左到右的, 而重載后無法保證此行為.- const PMFC Carrot::operator->*(ReturnType (T::*pmf)()) const {      ...} 【注】1. operator->* 重載比較少見, 有興趣可參考Implementing operator->* for Smart Pointers.- const Carrot* Carrot::operator&() const X {      ...} 【注】1. 你應(yīng)該盡量避免重載取地址操作符.- Coca& Carrot::operator*() {      ...} 【注】1. 重載提領(lǐng)操作符應(yīng)提供 const 版和非 const 版.· const Coca& Carrot::operator*() const- Coca* Carrot::operator->() {      ...} 【注】1. 重載 operator-> 應(yīng)提供 const 版和非 const 版.          2. operator-> 的返回值必須為一個指針或可以應(yīng)用 -> 操作的類型.          3. 如果 operator-> 的返回的不是一個指針, C++ 會繼續(xù)在返回類型上應(yīng)用 -> 直到得到一個指針為止.· const Coca* Carrot::operator->() const- Coca& Carrot::operator[](KeyType index) {      ...} 【注】1. operator[] 應(yīng)提供 const 版本和非 const 版.          2. KeyType 可以為任意類型, 但通常為 int 型.· const Coca& Carrot::operator[](KeyType index) const - AnyType Carrot::operator()(...) {      ...} 【注】1. operator () 重載的是函數(shù)運(yùn)算符, 改變表達(dá)式優(yōu)先級的 () 是不能重載的.          2. 重載了 operator() 的對象被成為仿函數(shù), 使用方法和函數(shù)指針類似.- static void* Carrot::operator new(size_t size, ...) {     if(size == 0)         size = 1;      while(1)     {          ... // allocate memery         if(allocate sucessfull)             return ... // return the pointer.         new_handler curhandler = set_new_handler(0);         set_new_handler(curhandler); // get current new handler         if(curhandler == 0)             (*curhandler)();         else             throw std::bad_alloc();     }【注】1. 參考重載 operator new.· static void* Carrot::operator new[](size_t size, ...)- static void Carrot::operator delete(void * memory, size_t size) {      if(memorty == NULL)         return;     ...} 【注】1. 參考重載 operator new.· static void Carrot::operator delete[](void * momery, size_t size)▲注:1.本文中成員函數(shù)僅指非靜態(tài)成員函數(shù);非成員函數(shù)包括自由函數(shù),靜態(tài)成員函數(shù),友元函數(shù)?!?.這種調(diào)用方法使用了 operator new 的一種重載形式: void * operator new(size_t, void * buff) . 這種重載方式直接返回了傳入的內(nèi)存地址, 所以這種調(diào)用方式中 operator new 其實什么也沒做, 于是這個 new operator 調(diào)用只使用了其中調(diào)用構(gòu)造函數(shù)的部分, 相當(dāng)于是在調(diào)用 placement new. 該重載在 VC7.1 中定義如下:#define __PLACEMENT_NEW_INLINEinline void *__cdecl operator new(size_t, void *_Where) _THROW0(){ // construct array with placement at _Wherereturn (_Where);}←3.和 placement new 一樣, nothrow new 也是 operator new 的一種重載形式, nothrow 是 中聲明的一個對象. 該重載在 VC7.1 中的聲明為:...struct nothrow_t     { // placement new tag type to suppress exceptions     };extern const nothrow_t nothrow; // constant for placement new tag...void *__cdecl operator new(size_t, const std::nothrow_t&)     _THROW0();←4.在 VC7.1 中, 不將 operator new 聲明為靜態(tài)函數(shù)仍然可以通過編譯, 但是如果在函數(shù)里面使用了非靜態(tài)成員則會產(chǎn)生編譯錯誤. 可見, 即使不將 operator new 聲明為靜態(tài)函數(shù)編譯器也會將其作為靜態(tài)函數(shù)來處理的. 使用是即使編譯器默認(rèn)把 operator new 當(dāng)作靜態(tài)函數(shù)也應(yīng)該顯式的將其聲明為 static 函數(shù). ←5. 即對 && 操作符如果左操作數(shù)為 false, 則直接返回 false 而不會去檢測右操作數(shù); 對 || 操作符如果左操作數(shù)為 true, 則直接返回 true 而不會檢測右操作數(shù)的值. 于是類似這樣的代碼可以是安全的:     if( (p != NULL) && strlen(p) < 10 )... 如果 p == NULL, strlen 就不會被調(diào)用. 但是重載的 operator&& 和 operator|| 是作為一個函數(shù), 要在所有的參數(shù)求值完成后才會調(diào)用此操作符.←
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C++ 中重載 + 操作符的正確方法
C++ operator關(guān)鍵字(重載操作符)
操作符重載
重載操作符解析
操作符重載!看這篇就夠了!
C++操作符重載(“=”)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服