程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> effective c++條款10-12(operator=(重載返回類型、自我賦值和深層復制))整理

effective c++條款10-12(operator=(重載返回類型、自我賦值和深層復制))整理

編輯:C++入門知識

effective c++條款10-12(operator=(重載返回類型、自我賦值和深層復制))整理


一、重載operator=返回類型
下面舉例說明,operator=類似。
針對:ostream & operator <<(ostream & os, const ClassType &object)

說明幾點:
1.第一個形參為對ostream對象的引用,在該對象上將產生輸出,ostream為非const,因為寫入到流會改變流的狀態;該形參是一個引用,因為不能復制ostream對象(在c++中定義的標准輸入輸出流類istream和ostream,其中拷貝構造函數和賦值操作符函數都被放置在了private部分,且只有聲明,沒有定義)。
2.第二個形參一般應是對要輸出的類類型的引用,該形參是一個引用以避免復制實參,減少一次拷貝;它設為const,因為輸出一般不會改變該對象,設為const就可以用來輸出const對象和非const對象。
3.返回類型是一個ostream引用,它的值通常是輸出操作符所操作的ostream對象,首先因為ostream對象不能復制,所以必須是引用;其次引用可以少一次拷貝,提高效率;最後,為了體現連續性,實現連續輸出,達到用多個輸出操作符操作一個ostream對象的效果,如果不是引用,程序返回的時候就會生成新的臨時對象,也就是說,連續的兩個<<操作符實際上是針對不同對象的,這就好比cout< PS: 重載賦值操作符,連續賦值可以不返回引用
重載加法操作符,連續相加不能返回引用

二、解決operator=自我賦值問題
在實現operator=時考慮自我賦值是必要的就像 x=y ,我們不知道變量x與y代表的值是否為同一個值(把x和y說成是一個指針更恰當一點)。如下

class bitmap{};
class Widget{
public:
    Widget& operator=(const Widget& rhn);
private:
    bitmap *pb; //定義一個指針指向對分配的空間
}
第一版賦值函數:
Widget& Widget::operator=(const Widget& rhs)
{
    delete pb;
    pb = new bitmap(*rhs.pb);
    return this;
}
這般函數的pb在使用前清理掉之前的pb指向,在接受一個new出來的新對象,看著很順理成章,但當 this 與函數的參數rhs相等時pb = new bitmap(*rhs.pb);會執行出錯,因為我們已經把*rhs.pb delete了。
第二版賦值函數:
Widget& Widget::operator=(const Widget& rhs)
{
    if(*this == rhs)
          return *this;
    delete pb;
    pb = new bitmap(*rhs.pb)
    return *this;


}
這個版本的賦值函數基本上是可以接受的,但不見的是安全的,因為當new產生異常時pb依然是個不確定的指針。
第三個版本:
Widget& Widget::operator=(const Widget& rhn)
{
    bitmap *pOrig = pb;
    pb = new bitmap(*rhn.pb);
    delete pOrig;
    return this;
}
這個函數在開始時用pOrig記錄了pb,當new沒有異常時我們在把Pb原來的指向空間釋放掉,從而提高了安全性。
實現賦值函數還有另外一個思想,即copy and swap技術
class Widget {


void swap(const Widget& rhs);


}

Widget& Widget::operator=(const Widget& rhs)    
{
    Widget temp(rhs);  //防止改變rhs
    swap(temp);
    return *this;


}
當然我們也可以by value 傳遞參數
Widget& Widget::operator=(const Widget rhs) //按值傳遞是實參的一個copy   
{
    swap(temp);
    return *this;


}
copy and swap技術的缺點是巧妙的運用swap喪失了代碼的清晰性,然而將“copy動作”移動到函數參數的構造階段令編譯器有時生成高效的代碼..

三、operator=重載函數、copy構造函數和構造函數深層復制

很容易理解啦,就是在子類中實現上述函數時,不要忘了調用基類的相應函數來復制、賦值和初始化繼承而來的那部分變量!!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved