《EffectiveC++》讀書筆記之二構造/析構/賦值運算

科技小能手發表於2017-11-13

《Effective C++》 讀書筆記之二 構造/析構/賦值運算

條款10:令賦值(assignment)操作符返回一個reference to *this。

例子:

1
2
3
4
5
Widget& operator=(const Widget& rhs)
{
    ...
    return *this;//返回*this
}

2016-11-03 09:36:00


條款11:在operator= 中處理“自我賦值”。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Widget{
    ...
    void swap(Widget& rhs);//交換*this與rhs的資料
    ...
};
 
//第一種合理安全的寫法
Widget& Widget::operator=(const Widget& rhs)
{
    BitMap * pOrg = pb;        //記住原先的pb
    pb = new BitMap(*rhs.pb);    //令pb指向*pb的一個復件(副本)
    delete pOrg;                //刪除原先的pb
    return *this;
}
//第二種合理安全的寫法
Widget& Widget::operator=(const Widget& rhs)
{
    Widget temp(rhs);
    swap(temp);
    return *this;
}

重點:

  1. 確保當物件自我賦值時operator= 有良好行為。其中技術包括比較“來源物件”與“目標物件”的地址、精心周到的語句順序、以及copy-and-swap。

  2. 確定任何函式如果操作一個以上的物件,而其中多個物件是同一個物件時,其行為仍然正確。

2016-11-03 10:23:50


條款12:複製物件時勿忘其每一個成分。Copy all parts of an object.

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void logCall(const std::string& funcName);
class Customer{
public:
    Customer(const Customer& rhs);.
    Customer& operator=(const Customer& rhs);
private:
    std::string name;
};
Customer::Customer(const Customer& rhs)
    :name(rhs.name) //複製所有成員,防止區域性拷貝(partial copy )
{
    logCall("Customer copy constructor");
}
Customer& Customer::operator=(const Customer& rhs)
{
    logCall("Customer copy assignment operator");
    name = rhs.name;
    return *this;
}
class PriorityCustmer: public Custmer //一個derived class
{
public:
    PriorityCustomer(const PriorityCustomer& rhs);
    PriorityCustomer& operator=(const PriorityCustomer& rhs);
private:
    int priority
};
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
    :Customer(rhs),//呼叫base class的copy建構函式,如果不呼叫,會呼叫Customer的default建構函式
    priority(rhs.priority)
{
    logCall("PriorityCustomer copy constructor");
}
PriorityCustomer&
PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
    logCall("PriorityCustomer copy assignment operator");
    Customer::operator=(rhs);//對base class成分進行賦值動作
    priority=rhs.priority;
    return *this;
}

重點:

  1. Copying函式應該確保複製“物件內的所有成員變數”及“所有base class成分”。

  2. 不要嘗試以某個copying函式實現另一個copying函式。應該將共同機能放進第三個函式中,比如init(),並由兩個copying函式共同呼叫。


本文轉自313119992 51CTO部落格,原文連結:http://blog.51cto.com/qiaopeng688/1868804


相關文章