c primer閱讀筆記 13章 1

2021-06-21 11:19:22 字數 2843 閱讀 5009

1、複製建構函式、賦值操作符和析構函式總稱為複製控制。編譯器自動實現這些操作,但類也可以定義自己的版本。

2、複製建構函式是一種特殊建構函式,具有單個形參,該形參(常用 const 修飾)是對該類型別的引用。當定義乙個新物件並用乙個同型別的物件對它進行初始化時,將顯式使用複製建構函式。當將該型別的物件傳遞給函式或函式返回該型別的物件時,將隱式使用複製建構函式。

3、析構函式是建構函式的互補:當物件超出作用域(???)或動態分配的物件被刪除時,將自動應用析構函式。析構函式可用於釋放構造物件時或在物件的生命期中所獲取的資源。不管類是否定義了自己的析構函式,編譯器都自動執行類中非 static類型別的 資料成員的析構函式。

4、與建構函式一樣,賦值操作符可以通過指定不同型別的右運算元而過載。右運算元為類型別的版本比較特殊:如果我們沒有編寫這種版本,編譯器將為我們合成乙個。

5、通常,編譯器合成的複製控制函式是非常精練的——它們只做必需的工作。但對某些類而言,依賴於預設定義會導致災難。實現複製控制操作最困難的部分,往往在於識別何時需要覆蓋預設版本。有一種特別常見的情況需要類定義自己的複製控制成員的:類具有指標成員(???)。

複製建構函式

1、只有單個形參,而且該形參是對本類型別物件的引用(常用 const 修飾),這樣的建構函式稱為複製建構函式。與預設建構函式一樣,複製建構函式可由編譯器隱式呼叫。複製建構函式可用於:

a:根據另乙個同型別的物件顯式或隱式初始化乙個物件。

b:複製乙個物件,將它作為實參傳給乙個函式。

c:從函式返回時複製乙個物件。

d:初始化順序容器中的元素。

e:根據元素初始化式列表初始化陣列元素。

2、c++ 支援兩種初始化形式(第 2.3.3 節):直接初始化和複製初始化。複製初始化使用 = 符號,而直接初始化將初始化式放在圓括號中。當初始化用於類型別物件時,初始化的複製形式和直接形式有所不同:直接初始化直接呼叫與實參匹配的建構函式,複製初始化首先使用指定建構函式建立乙個臨時物件(第 7.3.2 節),然後用複製建構函式將那個臨時物件複製到正在建立的物件。

3、支援初始化的複製形式主要是為了與 c 的用法相容。

形參與返回值

4、正如我們所知,當形參為非引用型別(第 7.2.1 節)的時候,將複製實參的值。類似地,以非引用型別作返回值時,將返回 return 語句 中的值的副本(第 7.3.2 節)。(形參與返回值為引用型別時,將不用複製。)

初始化容器元素

5、複製建構函式可用於初始化順序容器中的元素。例如,可以用表示容量的單個形參來初始化容器(第 3.3.1 節)。容器的這種構造方式使用預設建構函式和複製建構函式:

// default string constructor and five string copy constructors invoked

vectorsvec(5);

編譯器首先使用 string 預設建構函式建立乙個臨時值來初始化 svec,然後使用複製建構函式將臨時值複製到 svec 的每個元素。

作為一般規則(第 9.1.1 節),除非你想使用容器元素的預設初始值,更有效的辦法是,分配乙個空容器並將已知元素的值加入容器。

13.1.1. 合成的複製建構函式

1、如果我們沒有定義複製建構函式,編譯器就會為我們合成乙個。與合成的預設建構函式(第 12.4.3 節)不同,即使我們定義了其他建構函式(未定義複製建構函式),也會合成複製建構函式。合成複製建構函式的行為是,執行逐個成員初始化,將新物件初始化為原物件的副本。

所謂「逐個成員」,指的是編譯器將現在物件的每個非 static 成員,依次複製到正建立的物件。只有乙個例外,每個成員按型別決定了複製該成員的含義。合成複製建構函式直接複製內建型別成員的值,類型別成員使用該類的複製建構函式進行複製。陣列成員的複製是個例外。雖然一般不能複製陣列,但如果乙個類具有陣列成員,則合成複製建構函式將複製陣列。複製陣列時合成複製建構函式將複製陣列的每乙個元素。

13.1.2. 定義自己的複製建構函式

1、雖然也可以定義接受非 const 引用的複製建構函式,但形參通常是乙個 const 引用。因為用於向函式傳遞物件和從函式返回物件,該建構函式一般不應設定為 explicit(第 12.4.4 節)(???)。複製建構函式應將實參的成員複製到正在構造的物件。

2、有些類必須對複製物件時發生的事情加以控制。這樣的類經常有乙個資料成員是指標,或者有成員表示在建構函式中分配的其他資源(???)。而另一些類在建立新物件時必須做一些特定工作。這兩種情況下,都必須定義複製建構函式。

3、複製建構函式的定義與其他建構函式一樣:它與類同名,沒有返回值,可以(而且應該)使用建構函式初始化列表初始化新建立物件的成員,可以在函式體中做任何其他必要工作。

13.1.3. 禁止複製

1、有些類需要完全禁止複製。例如,iostream 類就不允許複製(第 8.1 節)。如果想要禁止複製,似乎可以省略複製建構函式,然而,如果不定義複製建構函式,編譯器將合成乙個。為了防止複製,類必須顯式宣告其複製建構函式為 private。

2、如果複製建構函式是私有的,將不允許使用者**複製該類型別的物件,編譯器將拒絕任何進行複製的嘗試。然而,類的友元和成員仍可以進行複製。如果想要連友元和成員中的複製也禁止,就可以宣告乙個(private)複製建構函式但不對其定義。宣告而不定義成員函式是合法的,但是,使用未定義成員的任何嘗試將導致鏈結失敗。通過宣告(但不定義)private 複製建構函式,可以禁止任何複製類型別物件的嘗試:使用者**中複製嘗試將在編譯時標記為錯誤,而成員函式和友元中的複製嘗試將在鏈結時導致錯誤。

3、般來說,最好顯式或隱式定義預設建構函式和複製建構函式。只有不存在其他建構函式時才合成預設建構函式。如果定義了複製建構函式,也必須定義預設建構函式。

c primer閱讀筆記 15章 1

1 物件導向程式設計基於三個基本概念 資料抽象 繼承和動態繫結。在 c 中,用類進行資料抽象,用類派生從乙個類繼承另乙個 派生類繼承基類的成員。動態繫結使編譯器能夠在執行時決定是使用基類中定義的函式還是派生類中定義的函式。15.1.物件導向程式設計 概述 1 物件導向程式設計的關鍵思想是多型性 po...

C Primer 閱讀筆記(1 2章)

1 用istream物件作為條件時,其效果是檢驗流的狀態。如果流是有效的,即未遇到未知錯誤,那麼檢測成功。當遇到檔案結束符,或遇到乙個無效輸入時,istream的物件將會變成無效,處於無效狀態的istream物件會使條件變為假。2 cerr 乙個ostream物件,寫入cerr的資料是不緩衝的,通常...

c primer閱讀筆記 15章 4

15.4.建構函式和複製控制 1 建構函式和複製控制成員不能繼承,每個類定義自己的建構函式和複製控制成員。15.4.1.基類建構函式和複製控制 1 本身不是派生類的基類,其建構函式和複製控制基本上不受繼承影響。15.4.2.派生類建構函式 1 派生類的建構函式受繼承關係的影響,每個派生類建構函式除了...