第十三章筆記 拷貝控制

2021-08-31 07:37:59 字數 2382 閱讀 1134

乙個類通過定義五種特殊的成員函式來控制這些操作,包括:拷貝建構函式(copy construcor),拷貝賦值運算子(copy-assignment operator)、移動建構函式(move constructor)、移動賦值運算子(move-assignment operator)和析構函式(destructor)。

1.拷貝建構函式的第乙個引數必須是乙個引用型別。

2.如果我們沒有給乙個類定義拷貝建構函式,則編譯器會定義乙個合成拷貝建構函式。(大致就是編譯器自己整的就叫合成拷貝建構函式)

3.直接初始化,實際上是要求編譯器使用普通的函式匹配來選擇與我們提供的引數最匹配的建構函式。

拷貝初始化,相當於將右側運算物件拷貝到正在建立的物件中,如果需要還要進行型別轉換。

4.標準庫通常要求儲存在容器中的型別要具有賦值運算子,且返回值是左側運算物件的引用。

1.它是類的乙個成員函式,名字由波浪號接類名構成。它沒有返回值,也不接受引數。因此不能被過載,即對乙個給定類,只會有唯一乙個析構函式。

2.合成析構函式不會delete乙個指標資料成員。

1.三個控制類拷貝操作的基本操作:拷貝建構函式,拷貝賦值運算子和析構函式(阻止拷貝)。

我們只能對具有合成版本的成員函式使用=default。

某個成員析構函式刪除/不可訪問->類的合成析構函式被定義為刪除

某個成員的拷貝建構函式/某個成員的析構函式<---->類的合成拷貝建構函式被定義為刪除

某個成員的拷貝賦值運算子->類的合成拷貝賦值運算子被定義為刪除

某個成員的析構函式/類有個引用成員,沒有類內初始化器->該類的預設建構函式定義為刪除

即如果乙個類有資料成員不能預設構造、拷貝、複製或銷毀,則對應的成員函式將被定義為刪除的。

不是很懂自賦值是什麼,書中舉例是當要釋放記憶體的物件與要拷貝的物件是同乙個時,會使指標空懸,導致出錯。

解決方法是通過拷貝和交換的賦值運算子,可以正確處理自賦值。

如果沒有移動建構函式,那麼為乙個vector重新分配記憶體的時候,就會引起從舊記憶體空間到新記憶體空間逐個拷貝string。

兩個機制:1.假定string的移動建構函式進行了指標的拷貝,而不是為字元分配記憶體空間然後拷貝字元。

2.乙個名為move的標準庫函式,呼叫move來表示希望用string的移動建構函式;

新標準的乙個最主要的特性是可以移動而非拷貝物件的能力。

8.1  右值引用

a.右值引用只能繫結到乙個將要銷毀的物件。

b.一般而言,乙個左值表示的是乙個物件的身份,而乙個右值表示的是乙個物件的值。

c.不能將乙個右值引用直接繫結到乙個左值上。

int &r2=i*42     //錯誤
d.但我們可以將乙個const的左值引用(常規引用)或者乙個右值引用繫結到非引用型別的函式

const int &r3 = i * 42  //正確

int &&rr2 = i * 42 //正確

8.2 左值持久:右值短暫

二者的區別:左值有持久的狀態,而右值要麼是字面常量,要麼是在表示式求值過程中建立的臨時物件。

使用右值引用的**可以自由地接管所用的物件的資源。

我們不能將乙個右值引用繫結到乙個右值引用型別的變數上:(這是由於變數是左值)

int &&rr1 = 42;    //正確:字面常量是右值

int &&rr2 = rr1; //錯誤:表示式rr1是左值!

但是我們可以通過呼叫乙個名為move的新標準庫函式來獲得繫結到左值上的右值引用

int &&rr3 = std::move(rr1);    //ok
呼叫move就意味著承諾:除了對rr1賦值或銷毀它外,我們將不再使用它。

我們可以銷毀乙個移後源物件,也可以賦予它新值,但不能使用乙個移後源物件的值

8.3 移動迭代器

與一般的迭代器解引用運算子返回乙個指向元素的左值不同,移動迭代器的解引用運算子生成乙個右值引用。

只有當確信演算法在為乙個元素賦值或將其傳遞給乙個使用者定義的函式後不再訪問它時,才能將移動迭代器傳遞給演算法。

第十三章 拷貝控制

在定義任何 c 類時,拷貝控制操作都是必要部分。如果我們不顯示定義這些操作,編譯器也會為我們定義,但編譯器定義的版本的行為可能並非我們所想。拷貝初始化不僅在我們用 定義變數時會發生,在下列情況下也會發生 將乙個物件作為實參傳遞給乙個非引用型別的形參 從乙個返回型別為非引用型別的函式返回乙個物件 用花...

第十三章 拷貝控制

如果乙個建構函式第乙個引數是自身類型別的引用,且任何額外引數都有預設值,則為拷貝建構函式 拷貝初始化發生情況 拷貝建構函式自己的引數必須是引用型別否則會遞迴死迴圈 拷貝賦值運算子是乙個名為 operator 的函式 建構函式初始化物件的非static資料成員 析構函式釋放物件使用的資源,並銷毀物件的...

第十三章 拷貝控制

拷貝控制操作 copy control 合成拷貝賦值運算子 合成析構函式 賦值運算子組合了析構函式和拷貝建構函式的工作,先在底層生成物件空間,刪除類內原有的記憶體空間,然後指向新分配的指標。hasptr operator const hasptr hp move函式 移動賦值運算子 合成的移動操作 ...