第13章 複製控制

2021-06-18 10:35:53 字數 1596 閱讀 1095

複製建構函式、賦值操作符和析構函式總稱為複製控制(copy control)。

複製建構函式可用於:(1)根據另乙個同型別的物件顯式或隱式初始化乙個物件;(2)複製乙個物件,將它作為實參傳給乙個函式;(3)從函式返回時複製乙個物件;(4)初始化順序容器中的元素,如vectorsev(5),分別用了預設建構函式和複製建構函式,先使用

string

預設建構函式建立乙個臨時值來初始化

svec

,然後用複製建構函式將臨時值複製到

svec

的每個元素;(5)根據元素初始化式列表初始化陣列元素(很多編譯器都優化了,不會呼叫拷貝建構函式)。

c++支援兩種初始化形式:直接初始化(將初始化式放在圓括號中,用與實參匹配的建構函式)和複製初始化(用=號,呼叫拷貝建構函式)。

對於如a a =string(「hello」);如果拷貝建構函式a(const string &)沒有定義為

explicit

,則初始化成功。

當形參為非引用型別的時候,將複製實參的值;以非引用型別作返回值時,將返回return語句中的值的副本。

如果我們沒有定義複製建構函式,編譯器就會為我們合成乙個(行為是逐個成員(非static)初始化)。

複製建構函式就是接受單個類型別引用形參(通常用const修飾,如a(const a&))的建構函式。

為了防止複製,類必須顯示宣告其複製建構函式為private。如果要是友元和成員中也禁止,則可以宣告但不定義。使用者**中的複製嘗試將在編譯時標記為錯誤,而成員函式和友元中的複製嘗試將在鏈結時導致錯誤。

過載操作符,形參表必須具有與該操作符運算元數目相同的形參。

當操作符成為成員函式時,它的第乙個運算元隱式繫結到this指標。因此賦值操作符接受單個形參,且該形參是同一類型別的物件,右運算元一般為const引用傳遞。如a& operator=(const a &);

合成賦值操作符根據成員型別使用適合的內建或類定義的賦值操作符,依次給每個成員賦值,該操作符返回

*this

,它是對左運算元物件的引用。

動態分配的物件只有在指向該物件的指標被刪除時才撤銷,沒有刪除會導致記憶體洩露。

容器中的元素總是按逆序撤銷。即首先撤銷下標最大的,依次往前。

三法則:如果類需要析構函式,則它也需要賦值操作符和複製建構函式。析構函式常用於釋放在建構函式或在物件生命週期內獲取的資源。

編譯器總是會為我們合成乙個析構函式,它按物件建立時的逆序撤銷每個非static成員(即它按成員在類中宣告次序的逆序撤銷成員,它不會刪除指標成員所指向的物件,因此需要顯示

delete)。

編寫了自己的析構函式,合成析構函式仍然執行。

一般的預設複製物件是淺拷貝,因此對於類中有指標的,複製後,兩個物件指向同乙個指標。因此會導致刪除了乙個物件的指標,另乙個物件的指標成員懸垂指標。

智慧型指標一般使用「計數」,引用計數。單獨定義乙個計數類(該類儲存對應類所需的指標(因此某個對應類如果改變指標指向,則所有指向該計數類的對應類指標指向都變了)和計數值,將要計數的類設為其友元,對應的類中將該計數類設為成員)。賦值操作先計數器加1再減少,防止自身賦值操作。

為了管理具有指標成員的類,必須定義三個複製控制成員:複製建構函式、賦值操作符和析構函式。

處理指標成員,還可以深拷貝。

第13章 複製控制 4

13.3 析構函式 析構函式可以完成資源 作為類建構函式的補充。1.何時呼叫析構函式 撤銷類物件時會自動呼叫析構函式。變數在超出作用域時應該自動撤銷。動態分配的物件只有在指向該物件的指標被刪除時才撤銷。如果沒有刪除指向動態物件的指標,則不會執行該物件的析構函式,物件就一直存在,從而導致記憶體洩漏,而...

第13章習題 複製控制

1.理解呼叫過程 include include using namespace std 定義exmpl類,該類給出複製控制成員和乙個預設建構函式,各成員函式輸出自己的名字。主程式中以不同方式使用exmpl型別的物件 作為非引用形參和引用形參傳遞,動態分配 作為函式返回值,進行賦值操作 作為元素放在...

第13章 複製控制 7

13.5.2 定義值型類 具有值語義的類所定義的物件,其行為很像算術型別的物件,反之亦然。string類是值型類的乙個例子。複製建構函式不再複製指標,它將分配乙個新的int物件,並初始化該物件以儲存與被複製物件相同的值。每個物件都儲存屬於自己的int值的不同副本。因為每個物件儲存自己的副本,所以析構...