C++基礎回顧5——類的拷貝、複製和銷燬

愛上冰激凌發表於2018-06-06

拷貝建構函式

class Foo
{
    Foo(); //預設建構函式
    Foo(const Foo&); //拷貝建構函式
}

拷貝建構函式的第一個引數必須是引用型別,在函式呼叫過程中,具有非引用型別的引數要進行拷貝初始化。同樣,當一個函式具有非引用的返回型別時,返回值會被用來初始化呼叫方法的結果。
因此,如果拷貝建構函式的引數不是引用型別,為了呼叫拷貝建構函式,我們必須拷貝實參,這個過程又需要呼叫拷貝建構函式,如此將是一個無限迴圈。

一般而言,合成拷貝建構函式會將其引數的成員逐個拷貝到正在建立的物件中:
類型別->使用其拷貝建構函式來拷貝;
內建型別->直接拷貝;
陣列型別->逐個元素拷貝至一個陣列,如果陣列的元素是類型別,則使用元素的拷貝建構函式來進行拷貝。

    string dot(10, '.');  //直接初始化
    string s(dot);      //直接初始化
    string s2 = dot;    //拷貝初始化
    string null_book = "99-99-99-99-99";  //拷貝初始化
    string nines = string(100, '9');      //拷貝初始化

直接初始化:要求編譯器使用普通的函式匹配;
拷貝初始化:用拷貝構造初始化將右側的物件拷貝至正在建立的物件中。
拷貝初始化的發生情況:

  • 將物件作為實參傳遞給非引用型別的形參;
  • 從返回型別為非引用型別的函式;
  • 用花括號列表初始化一個陣列中的 元素或一個聚合類中的成員。

    拷貝賦值運算子

    賦值運算子通常返回一個指向其左側運算物件的引用

class Foo
{
    public:
        Foo(); //預設建構函式
        Foo& operator=(const Foo&);   //賦值運算子
    //...
};

過載運算子的參數列示運算子的操作物件,某些運算子,包括賦值運算子,必須定義為成員函式。如果一個運算子是一個成員函式,其左側運算物件就繫結到隱式的this引數上。

Sales_data& 
Sales_data::operator=(const Sales_data& rhs)
{
    bookNo = rhs.bookNo;
    units = rhs.units;
    revenue = rhs.revenue;
    return *this;
}

解構函式

在一個解構函式中,首先執行函式體,然後銷燬成員。成員按初始化的順序逆序銷燬。銷燬類成員需要執行成員自己的解構函式。

是麼時候呼叫解構函式:
- 變數在離開其作用域時銷燬;
- 當一個物件被銷燬時,其成員被銷燬;
- 容器被銷燬,其元素也會被銷燬;
- 動態分配的物件,應用delete時被銷燬
- 對於臨時物件,建立完整表示式結束時被銷燬
-

相關文章