C++構造函數詳解(脫坑指北)

默認構造函數

首先有一點很重要,就是在c++中,如果我們自己沒有聲明,編譯器會暗自幫我們聲明拷貝構造函數、析構函數、賦值操作符,假如我們沒有聲明任何構造函數的話,編譯器還會幫我們聲明一個缺省的構造函數。這些編譯器幫我們聲明的函數都是公有的而且是內聯的。只不過,這些函數只是被聲明,並沒有直接進行創建,只有當這些函數被調用到的時候,它們纔會被編譯器創建出來。
其次就是,只有當我們在類中沒有聲明任何構造函數時,編譯器纔會幫我們聲明一個無參的缺省的構造函數,一旦我們聲明瞭別的任何構造函數,編譯器就不會幫我們聲明瞭。舉個例子,假如我們在一個類中只寫了一個有參構造函數,此時編譯器會幫我們聲明拷貝構造、析構、賦值操作符,但不會再幫我們再去聲明一個無參的缺省構造函數,也就是說此時的這個類它是沒有無參構造函數,我們就不能以無參的方式去實例化一個類對象。(感覺這句話挺費心的,其實就是用自己設計的類型去定義一個該類型的變量,就像用int 定義一個i變量一樣)
這一段廢話挺多的就是怕說不清楚了。仔細看看應該都能理解。

class Student
{
public:
	//拷貝構造函數
	Student(const int i):m_i(i){}
private:
	int m_i;
};

上面這個類,我們不能這樣實例化類對象:Student std; 只能這樣 Student stu(10)。

只有一個參數的構造函數

俗稱單參數構造函數,舉個例子:

class Teacher 
{
public:
	Teacher(){}
	Teacher(const int i):m_i(i){}
private:
	int m_i;
};

int main(void)
{
	Teacher tea=1;
	//我們可以這樣去實例化一個對象,它會自動匹配到單個參數構造函數
	//但是我們一般不建議去這樣使用,容易給代碼閱讀者帶來困擾(爲什麼一個
	//int型可以賦值給一個Teacher類對象?)
	//期間有發生類型轉換
}

爲了保證只能通過顯示的類型轉換才能使用,我們引入explicit關鍵字。

拷貝構造函數

在我們自己沒有聲明拷貝構造函數時,編譯器會暗自幫我們聲明一個,並在調用到時創建它。編譯器創建的版本只是單純的把每一個非靜態成員變量拷貝到目標對象。如果成員變量中有類類型成員,就會調用該成員子對象的拷貝構造函數去初始化。如果成員變量是內置類型就會直接進行拷貝。

還有一個需要注意的就是,成員變量是const聲明或者是引用類型時,我們知道在c++中並不允許讓引用改指向不同對象,const類型值也是不可改變的。面對這個問題我們就需要自己去定義這個拷貝構造函數。(想解決這個問題我們就需要用到初始化列表),構造函數的執行是分爲初始化階段和計算階段這兩個階段的。(具體自行百度)

最後一個要說得問題就是深拷貝和淺拷貝。編譯器爲我們暗自創建得拷貝構造函數和賦值操作符都是淺拷貝,如果需要深拷貝需要自行定義。(詳解深淺拷貝請自行百度)。

要說得好像也就這麼多了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章