c++--類的構造函數與拷貝控制
類(class)與結構體(struct)的位移區別在於:默認情況下,類的派生方式和訪問權限是private的,struct的派生方式和訪問權限是public的。
構造函數
構造函數的任務是初始化類對象的數據成員,無論何時只要類的對象被創建,就會執行構造函數。
特點1:不同於其他成員函數,構造函數不能被聲明為const的(參見7.1.2,P231)。
當我們創建類的一個const對象時,直到構造函數完成初始化過程,對象才能真正取得其“常量屬性”。因此,構造函數在const對象的構造過程中可以向其寫值。
const Sales_data obj(); //const對象
const成員函數:
const的作用是修改隱式this指針的類型。默認情況下,this 的類型是指向類類型非常量版本的常量指針,如在Sales_data成員函數中,this 的類型是 Sales_data *const。這意味著,在默認情況下,不能把this綁定到一個常量對象上。所以,應該將那些“不會修改類對象”的成員函數定義為const 的。如string isbn();
1 string Sales_data::isbn() const //this 類型為 const Sales_data *const 2 {return this->isbn;}
合成默認構造函數
如果沒有顯式的定義構造函數,那麽編譯器會為我們隱式的定義一個合成的默認構造函數。
初始化規則:1,如果存在類內的初始值(有默認值),用他來初始化成員;2,否則,默認初始化該成員。
某些類(比如包含不能依賴默認初始化的類型成員時)不能依賴於合成的默認構造函數。一般要自定義默認構造函數。
默認構造函數(=default)
一般要為類定義一個默認構造函數(=default):
1 struct Sales_data 2 { 3 Sales_data()=default; //他的作用完全等同於合成默認構造函數 4 Sales_data(const string &s):bookNo(s){} 5 ... 6 }
有一種情況必須去掉“=defalut”的默認構造函數
如果還有原來的“=default”版本,在“Sales_data A;”時,編譯器不知道調用哪個版本的構造函數,將出現“二義性”。
構造函數初始值列表
如果成員是const、引用,或者屬於某種未提供默認構造函數的類類型,我們必須通過構造函數初始值列表為這些成員提供初始值。
//構造函數,版本1 Sales_data::Sales_data(const string &s,unsigned n,double p) { bookNo=s; units_sold=n; revenue=n*p; } //構造函數,版本2 Sales_data(const string &s,unsigned n,double p): bookNo(s),units_sold(n),revenue(p*n){}
版本2采用了初始值列表,兩個版本效果相同。區別在於:版本2初始化了他的數據成員,二版本1對數據成員執行了賦值操作。
成員初始化的順序:與它們在類定義中的出現順序一致,第一個成員先被初始化,然後第2個,以此類推。構造函數初始值列表中初始值的前後位置不會影響實際的初始化順序。
五種特殊的成員函數:拷貝構造函數、拷貝賦值運算符、移動構造函數、移動賦值運算符和析構函數。
拷貝構造函數和移動狗制造函數定義了【當用同類型的另一個對象初始化本對象時做什麽】。拷貝和移動賦值運算符定義了【將一個對象賦予同類型的另一個對象時做什麽】。析構函數定義了【當此類型對象銷毀時做什麽】。
c++--類的構造函數與拷貝控制