effective c++ 筆記 (4)

來源:互聯網
上載者:User

標籤:effective c++   筆記   c++   

//---------------------------15/03/29----------------------------


//#9    絕不在構造和析構過程中調頭virtual函數

{

   /*

        1:在構造時調用virtual函數有兩個結果

            1>如果基類實現了這個函數,就調用基類的函數。

            2>基類沒有實現這個函數,連結時報錯。

            原因:

            1>基類的建構函式是早於 衍生類別的建構函式調用的,所以如果virtual函數使用衍生類別版本的

            話,很可能用到未初始化的衍生類別的成員變數。c++為了不讓你走這條危險的路,就會只調用基類的版本

            2>根本原因:在調用基類建構函式時,物件類型是base class,所以會調用基類版本。

            所以不要在建構函式中調用任何virtual函數。

        2:在解構函式中調用vitual函數:

            由於衍生類別的解構函式是先於基類調用的,所以輪到基類的建構函式時,衍生類別的成員變數依舊呈現

            未定義狀態。所以c++視它們不存在,在調用基類解構函式時,對象稱為一個base class對象。

        3:為了在衍生類別對象建立時,基類中有適當版本的顯示資訊調用,一個解決辦法是由衍生類別傳入一個訊息,

        再調用non_virtual版本來顯示。

     

     

     

    */

}


//#10   令 operator= 返回一個reference to *this

{

   /*

        關於賦值,c++中可以寫成連鎖形式:

        int x,y,z;

        x = y = z = 15;

        為了實現這種連鎖賦值,賦值操作符必須返回一個reference指向操作符的左側實參。

                                                                        */

   class Widget

    {

    public:

        Widget&operator=(const Widget& rhs)

        {

            ...

           return *this;

        }

    };

}


//#11   在operator=中處理自我賦值

{

    //看下面的函數

    Widget&

    Widget::operator=(const Widget& rhs)

    {

       delete pb;

        pb =new Bitmap(*rhs.pb);

       return *this;

    }

    //這樣如果是自我賦值,那就先delete了pb,最後pb就指向一個已經刪除的對象

    //如果讓operator=具備異常安全性 往往自動獲得自我賦值安全。

    Widget& Widget::operator=(const Widget& rhs)

    {

        Bitmap* pOrig = pb;

        pb =new Bitmap(*rhs.pb);

       delete pOrig;

       return *this;

    }

    //這麼做會有效率問題:如果是自我賦值,那就多做了一次new以及delete;但是考慮到自我賦值的幾率

    //並不建議在開頭加上if判斷來判斷是否是自己。而且用了if語句,效率會明顯下降

    //還有種方法是使用swap保證異常安全性

    Widget& Widget::operator=(const Widget& rhs)

    {

        Widget temp(rhs);

        swap(temp);

       return *this;

    }

    

}


//#12   複製對象時勿忘其每一個成分

{

   /*

        1:當你自己實現operator=操作時,如果你忘記了一個成員變數的複製,編譯器不會警告你

        2:當你寫自己的operator=或者copy建構函式時應該記得:

            1>複製所有的自己的成員變數

            2>調用所有base classes內的適當的copying函數。

        3:如果發現copy建構函式和copy assignment操作符有相近的代碼,消除重複代碼的做法是

        建立一個init成員函數,供兩者調用。(但是考慮到前面的條目,建構函式直接初始化效率會很高,所以

        如果相近的代碼只是賦值的話,還是多動手的好)

     

    */

    PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)

    :Customer(rhs), priority(rhs.priority)

    {

        ...

    }

    

    PriorityCustomer&

    PriorityCustomer::operator=(const PriorityCustomer& rhs)

    {

        ...;

        Customer::operator=(rhs);

        prioriy = rhs.priority;

       return *this;

    }

}












effective c++ 筆記 (4)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.