1、顯式建構函式
複製建構函式是一種特殊建構函式,具有單個形參,該形參(常用 const 修飾)是對該類類型的引用。當定義一個新對象並用一個同類型的對象對它進行初始化時,將顯式使用複製建構函式。當將該類型的對象傳遞給函數或函數返回該類型的對象時,將隱式使用複製建構函式。
編譯器自動執行類中非static資料成員的解構函式。
2、賦值操作符可以通過指定不同類型的右運算元而重載。
3、有一種特別常見的情況需要自己定義的複製控製成員的:類具有指標成員。
4、C++支援兩種初始化形式:直接初始化和複製初始化。複製初始化使用=,而直接初始化將初始化放在圓括弧中。
當用於類類型對象時,初始化的複製形式和直接形式有所不同:直接初始化直接調用與實參匹配的建構函式,複製初始化總是調用複製建構函式。複製初始化首先使用指定建構函式建立一個臨時對象,然後用複製建構函式將那個臨時對象複製到正在建立的對象:
樣本
string null_book = "00000"; //拷貝建構函式
string dotc(10, '.'); //直接初始化
string empty_copy = string(); //拷貝建構函式
string empty_direct; //直接初始化
5、以非參考型別作為傳回值時,將返回return語句中的值的副本。
6、合成的複製建構函式
如果我們沒有定義複製建構函式,編譯器就會為我們合成一個。合成複製建構函式的行為是,執行逐個成員初始化,將新對象初始化為原對象的副本。
所謂“逐個成員”,指的是編譯器將現在對象的每個非 static 成員,依次複製到正建立的對象。只有一個例外,每個成員的類型決定了複製該成員的含義。合成複製建構函式直接複製內建類型成員的值,類類型成員使用該類的複製建構函式進行複製。數群組成員的複製是個例外。雖然一般不能複製數組,但如果一個類具有數群組成員,則合成複製建構函式將複製數組。複製數組時合成複製建構函式將複製數組的每一個元素。
7、大多數類應定義複製建構函式和預設建構函式。不允許複製的類對象只能作為引用傳遞給函數或從函數返回,它們也不能用作容器的元素。只有不存在其他建構函式時才合成預設建構函式。
8、內建類型的賦值運算返回對左運算元的引用。
樣本
class Sales_item
{
public:
Sales_item& operator=(const Sales_item&rhs)
{
isbn = rhs.isbn;
units_sold = rhs.units_sold;
revenue = rhs.revenue;
return *this; //返回左運算元的引用
}
};
9、合成賦值操作符與合成複製建構函式的操作類似。它會執行逐個成員賦值:右運算元對象的每個成員賦值給左運算元對象的對應成員。除數組之外,每個成員用所屬類型的常規方式進行賦值。對於數組,給每個數組元素賦值。
10、解構函式
當對象的引用或指標超出範圍時,不會運行解構函式。只有刪除指向動態指派至的指標或實際對象(不是對象的引用)超出範圍時,才會運行解構函式。
如果類需要解構函式,則它也需要賦值操作和複製建構函式,這是一個有用的經驗法則(通常稱為三法則)。
11、與複製建構函式或賦值操作符不同,編譯器總是會我們合成一個解構函式。合成解構函式按對象建立時的逆序撤銷每個非static成員。合成解構函式並不刪除指標成員所指向的對象。
12、解構函式沒有形參,不能重載。即使我們編寫了自己的解構函式,合成解構函式仍然運行。(先運行自訂的,再運行合成的)
13、解構函式對撤銷內建類型或指標類型的成員沒有影響。賦值操作必須是類的成員並且必須返回對類對象的引用。
關於複製建構函式中涉及的深拷貝,淺拷貝,及與賦值操作的異同,可以參見下列文章。
參考
[1] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100250413207/
[2] http://blog.163.com/zhoumhan_0351/blog/static/39954227201032845132592/
[3] http://blog.163.com/zhoumhan_0351/blog/static/399542272010318112048522/
[4] http://blog.163.com/zhoumhan_0351/blog/static/39954227201032092854732/
[5] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100284731826/
[6] http://blog.163.com/zhoumhan_0351/blog/static/39954227201012465955824/