c++的類有六個默認成員函數,我今天介紹其中的兩個,一個是構造函數另外一個是拷貝構造函數。c++
構造函數用於當類的對象被建立時,給它分配內存空間,而且由編譯器自動調用構造函數對類對象進行初始化工做。ide
構造函數的函數名與類名相同,沒有返回類型。下面是一個例子:函數
class String { public: String() { } private: char* _pStr; }
這個時候String就是咱們String類的構造函數,固然它如今什麼都沒有作。spa
構造函數能夠對類對象這樣進行初始化:orm
String(const char* pStr = "") :_pStr(new char[strlen(pStr) + 1]) { strcpy(_pStr, pStr); }
這幾行代碼對類對象進行了初始化。首先由函數接收一個參數(假如沒有給參數那麼缺省爲「」,並且缺省的構造函數只能有一個),後面冒號後面的是初始化列表,初始化列表以冒號開始,中間用逗號隔開,每一個成員只能出現一次,初始化的順序也要按照成員定義的順序。在上面的例子中咱們給成員初始化了一塊空間,而且在函數內部調用strcpy函數把字符串的內容也拷貝進去了。對象
固然你的構造函數能夠沒有參數,讓它在函數內部進行初始化,也能夠經過初始化列表進行初始化。內存
好比這樣:字符串
class Complex { public: Complex(double real = 0.0, double p_w_picpath = 0.0) :_real(real), _p_w_picpath(p_w_picpath) { } private: double _real; double _p_w_picpath; }
或者這樣:編譯器
class Complex { public: Complex(double real = 0.0, double p_w_picpath = 0.0) { _real=real; _p_w_picpath=p_w_picpath; } private: double _real; double _p_w_picpath; }
假如你的類沒有顯示的定義一個構造函數,那麼編譯器會給你生成一個。it
下面介紹拷貝構造函數。拷貝構造函數是一種特殊的構造函數,函數名也和類名是同樣的,它的惟一的一個參數是本類型的一個引用變量。固然,參數最好要聲明爲const,起到一個保護的做用。
那麼何時會調用拷貝構造函數呢?當用一個已初始化過了的自定義類類型對象去初始化另外一個新構造的對象的時候,拷貝構造函數就會被自動調用。也就是說,當類的對象須要拷貝時,拷貝構造函數將會被調用。如下狀況都會調用拷貝構造函數:
① 當咱們要用一個對象去初始化另外一個對象時。
② 當函數的參數爲類的對象時。
③ 函數的返回值是類的對象。
下面咱們舉一個例子:
String(const char* pStr = "") :_pStr(new char[strlen(pStr) + 1]) { strcpy(_pStr, pStr); } String(const String& s) { String strTemp(s._pStr); std::swap(_pStr, strTemp._pStr); }
在這個例子中,上面的是構造函數,下面的是拷貝構造函數。
如上文所說,它的參數是const類對象的一個引用變量,在函數內部對新的類對象進行了初始化。假如咱們不顯式的定義拷貝構造函數,那麼編譯器給咱們的會是一個進行淺拷貝的函數。那麼在咱們進行清理,把咱們申請的空間進行釋放的時候,就會產生問題。因此咱們在寫程序的時候要儘可能顯顯式的定義構造函數和拷貝構造函數。