1、顯式構造函數
複制構造函數是一種特殊構造函數,具有單個形參,該形參(常用 const 修飾)是對該類類型的引用。當定義一個新對象并用一個同類型的對象對它進行初始化時,将顯式使用複制構造函數。當将該類型的對象傳遞給函數或函數傳回該類型的對象時,将隐式使用複制構造函數。
編譯器自動執行類中非static資料成員的析構函數。
2、指派操作符可以通過指定不同類型的右操作數而重載。
3、有一種特别常見的情況需要自己定義的複制控制成員的:類具有指針成員。
4、C++支援兩種初始化形式:直接初始化和複制初始化。複制初始化使用=,而直接初始化将初始化放在圓括号中。
當用于類類型對象時,初始化的複制形式和直接形式有所不同:直接初始化直接調用與實參比對的構造函數,複制初始化總是調用複制構造函數。複制初始化首先使用指定構造函數建立一個臨時對象,然後用複制構造函數将那個臨時對象複制到正在建立的對象:
示例
5、以非引用類型作為傳回值時,将傳回return語句中的值的副本。
6、合成的複制構造函數
如果我們沒有定義複制構造函數,編譯器就會為我們合成一個。合成複制構造函數的行為是,執行逐個成員初始化,将新對象初始化為原對象的副本。
所謂“逐個成員”,指的是編譯器将現在對象的每個非 static 成員,依次複制到正建立的對象。隻有一個例外,每個成員的類型決定了複制該成員的含義。合成複制構造函數直接複制内置類型成員的值,類類型成員使用該類的複制構造函數進行複制。數組成員的複制是個例外。雖然一般不能複制數組,但如果一個類具有數組成員,則合成複制構造函數将複制數組。複制數組時合成複制構造函數将複制數組的每一個元素。
7、大多數類應定義複制構造函數和預設構造函數。不允許複制的類對象隻能作為引用傳遞給函數或從函數傳回,它們也不能用作容器的元素。隻有不存在其他構造函數時才合成預設構造函數。
8、内置類型的指派運算傳回對左操作數的引用。
9、合成指派操作符與合成複制構造函數的操作類似。它會執行逐個成員指派:右操作數對象的每個成員指派給左操作數對象的對應成員。除數組之外,每個成員用所屬類型的正常方式進行指派。對于數組,給每個數組元素指派。
10、析構函數
當對象的引用或指針超出作用域時,不會運作析構函數。隻有删除指向動态配置設定對象的指針或實際對象(不是對象的引用)超出作用域時,才會運作析構函數。
如果類需要析構函數,則它也需要指派操作和複制構造函數,這是一個有用的經驗法則(通常稱為三法則)。
11、與複制構造函數或指派操作符不同,編譯器總是會我們合成一個析構函數。合成析構函數按對象建立時的逆序撤銷每個非static成員。合成析構函數并不删除指針成員所指向的對象。
12、析構函數沒有形參,不能重載。即使我們編寫了自己的析構函數,合成析構函數仍然運作。(先運作自定義的,再運作合成的)
13、析構函數對撤銷内置類型或指針類型的成員沒有影響。指派操作必須是類的成員并且必須傳回對類對象的引用。
關于複制構造函數中涉及的深拷貝,淺拷貝,及與指派操作的異同,可以參見下列文章。
參考