1. 程式人生 > >C++類的六大函數--構造、析構、拷貝構造、移動構造、拷貝賦值、移動賦值

C++類的六大函數--構造、析構、拷貝構造、移動構造、拷貝賦值、移動賦值

con 析構 mil cit 分享 新的 進入 ons 移動

1.拷貝構造函數和移動構造函數

總的來說,都是用一個已有的對象去創建構造一個新的對象。

當對象中含有指針或類作為數據成員的,對於已有的對象在構造出新的對象後,仍需要對該已有對象進行引用或利用的,需要我們自己定義拷貝構造函數(進行深拷貝)。

而對於已有的對象在構造出新的對象後,將不再對該已有對象進行引用或利用的,需要我們自己定義移動構造函數(進行淺拷貝)。

拷貝構造函數和移動構造函數調用規則可以按下圖1-1進行:

技術分享圖片

1-1 拷貝構造函數和移動構造函數的簡單調用規則圖

2.拷貝賦值函數和移動賦值函數

對於拷貝賦值和移動賦值,則都是用一個已有對象將其值賦值給另一個已有對象。

其調用賦值函數類型的規則與拷貝構造函數和移動構造函數調用規則相似,都是根據對象是否繼續進行利用選擇,調用規則可以按下圖

1-2進行:

技術分享圖片

1-2 拷貝賦值和移動賦值的簡單調用規則圖

代碼測試實驗代碼:

    //拷貝構造函數
    vector (const vector &rhs ):theSize{rhs.theSize},
        theCapacity{ rhs.theCapacity }, objects{ nullptr }
    {
        objects = new Object[theCapacity];
        for (int i = 0; i < theSize; ++i)
            objects[i] 
= rhs.objects[i]; std::cout << "拷貝構造" << std::endl; } //拷貝賦值函數 vector & operator =(const vector &rhs) { vector copy = rhs; std::swap(*this, copy); /*利用移動交換 void swap(vector<object> &x,vector <object> &y) { vector<object> temp = std:: move( x ); x = std::move( y ); y = std::move( temp ); } 若是利用賦值交換,則會進入死循環 void swap((vector<object> &x,vector <object> &y) { vector<object> temp = x ; //這裏會重新調用賦值函數,陷入死循環 x = y ; y = temp ; }
*/ std::cout << "拷貝賦值" << std::endl; return *this; } //移動構造函數 vector (vector && rhs):theSize{rhs.theSize}, theCapacity{ rhs.theCapacity }, objects{ rhs.objects }//objects 這裏與拷貝構造函數不同了,拷貝的是null { rhs.objects = nullptr; rhs.theSize = 0; rhs.theCapacity = 0; std::cout << "移動構造" << std::endl; } //移動賦值函數 vector &operator =(vector && rhs) { std::swap(theSize, rhs.theSize); std::swap(theCapacity, rhs.theCapacity); std::swap(objects, rhs.objects); /*利用賦值交換 void swap((vector<object> &x,vector <object> &y) { vector<object> temp = x ; x = y ; y = temp ; } 若是利用移動交換,則會進入死循環 void swap(vector<object> &x,vector <object> &y) { vector<object> temp = std:: move( x ); //這裏會重新調用移動函數,陷入死循環 x = std::move( y ); y = std::move( temp ); } */ std::cout << "移動賦值" << std::endl; return *this; }

C++類的六大函數--構造、析構、拷貝構造、移動構造、拷貝賦值、移動賦值