作用:
1)分配空間:分配非靜態數據成員的存儲空間
2)初始化成員:初始化非靜態數據成員
分配空間:
1)含有指針變量,需要程序員顯式申請空間(使用new申請)
2)非指針變量:由系統自動分配空間
初始化成員:
1)使用賦值語句初始化:一般的變量
2)使用表達式表初始化:一般的變量 + Const成員,引用成員,對象成員
調用時機:在定義對象的時候,系統自動調用構造函數
1)對象被創建時,自動調用構造函數
Coord p1(1);
Coord p2=1; //此時也會調用構造函數,但是有前提:構造參數只能有一個參數
2)如果對象是用new 創建時,自動調用構造函數。
語法:名字和類名相同、無返回類型、允許為內聯函數、重載函數、帶默認形參值的函數
代碼:
class A { private: int x; int& rx; const float pi; public: A(int x1):rx(x),pi(3.14)//rx(x)等價於rx=x,pi(3.14)相當於pi=3.14 { x=x1;//一般的變量 } }; 調用:A a(10);
成員初始化表的使用
語法:
類名::構造函數名(參數表):(數據成員名1(初始值1),數據成員名2(初始值2),…… )
{
函數體
}
說明:
1、類成員的初始化:按照他們在類中聲明的順序進行初始化,與他們在成員初始化表中的順序無關
2、數據成員含數組時,應在構造函數中通過賦值語句實現,不能使用成員初始化表
作用:釋放空間:
1)含有指針變量,需要程序員顯式釋放空間
2)非指針變量:由系統自動釋放空間
調用時機:
1)對象被撤銷時,如對象定義在函數內,當函數調用結束時,該對象被撤銷。
2)如果對象是用new 創建的,當delete它時,自動調用析構函數。
語法:沒有返回類型,沒有參數,函數名是類名前加 "~"
代碼:
class X { public: X() { } ~X() { } };
說明:
1、為什麼要把析構函數定義為虛函數?
因為:虛函數是為了支持多態,。。。之後補充
遇到的問題
#includeusing namespace std; class AAA { public: AAA(void); ~AAA(void); }; AAA::AAA() { }; int main() { AAA t; //報錯 AAA *p = new AAA(); //不報錯 system("pause"); return 1; }
問題分析:因為編譯器為每一個類都會聲明一個默認的構造函數和析構函數,拷貝構造函數、賦值運算符。當用戶自己定義時,系統就不在為類自動生成。這裡類中已經自己定義了構造函數和析構函數,系統就沒有自己生成。
AAA t;//報錯
原因:在堆上定義對象是,系統會自動調用構造函數和析構函數。在鏈接時,系統會發現找不到析構函數的實現,這時就會報錯,說找不到析構函數。要用你但是找不著你就會報錯
AAA *p = new AAA(); //不報錯
原因:new的時候會調用構造函數,但是由於釋放的時候需要用戶自己手動釋放,這裡由於沒有delete,所以,不會用到析構函數。在程序鏈接時,由於沒有用到析構函數,就沒有去找其實現,就不會報錯
int main() { //AAA t; //報錯 AAA *p = new AAA(); delete p; //報錯 system("pause"); return 1; }
如上的例子,如果寫delete
AAA *p = new AAA(); //不報錯
delete p;
這時程序執行delete時,需要用到析構函數。鏈接時,系統就會找其實現。當發現沒實現時,而報錯。
所以,我們在聲明了函數就要記得實現,尤其是構造函數和析構函數,拷貝構造函數、賦值運算符。