參考自:https://blog.csdn.net/sunSHINEEzy/article/details/78122485
- 構造函數之默認構造函數(調用的構造函數不用傳遞參數)


兩種實例化方式都是默認構造函數
- 構造函數之初始化列表
紅字部分即為初始化列表:一個引號,多個參數用逗號隔開,賦值用()
初始化列表特性:
- 其先於構造函數執行
- 其只能用於構造函數
- 其可以同時初始化多個數據成員
- 【注意】初始化列表的功用:對於類中的靜態常量,不能用構造函數來初始化,必須使用初始化列表的方式
- 拷貝構造函數

拷貝構造函數的特點:
-
- 當用戶沒有定義構造函數時,編譯器會自動生成一個默認的拷貝構造函數(構造函數也是如此)
- 當采用直接初始化或復制初始化實例化對象時,系統會自動調用拷貝構造函數
- 由於拷貝構造函數的特性,拷貝構造函數不能重載!!
- 【總結】構造函數總結:
- 【總結】所有參數帶有默認值時,轉變成了默認構造函數
【注意】初始化列表是所有構造函數都可以實現的.
- 析構函數(用於釋放系統資源的函數)
定義格式:
析構函數特點:- 如果沒有自定義的析構函數,則系統自動生成
- 析構函數在對象銷毀時自動調用(與之相對應,構造函數在對象實例化時自動調用)
- 析構函數沒有返回值(構造函數也是如此)、沒有參數也不能重載
- 不允許在()內加任何的參數
- 【重要知識點】對象的生命歷程

- 【總結】成員函數的分類
成員函數的參數修飾方式
對象實例化的方式
定義一個函數只要不是函數聲明,就要記着寫{},即使{}不寫任何的語句。
總結:構造函數與析構函數的調用順序
1、先執行 被組合對象的構造函數
(1)當類中有成員變量是其他類的對象時,首先調用成員變量的構造函數,調用順序與聲明順序相同,之后調用自身類的構造函數。
(2)析構函數的調用順序與對應的構造函數調用順序相反。
2、被組合對象的構造順序,預定義順序有關系,與初始化列表的順序沒有關系
3、 特殊成員變量必須用參數列表初始化。const、&、對象。
4、static類型的成員變量,必須在類外初始化,且不帶static關鍵字。
注意:構造函數中不要調用構造函數!!這是一種危險的行為!(匿名對象深究)
#include<iostream> #include<string> using namespace std; class Point { public: Point(int a,int b,int c) { this->a = a; this->b = b; this->c = c; cout << "這是Pointd的有3個默認參數的構造函數! "<<this->a<<" "<<this->b<<" "<<this->c<<endl; } Point(int a, int b) { this-> a= a; this->b = b; Point(3, 4, 5);//產生一個匿名對象,紙條語句執行結束,匿名對象會被析構。 cout << "這是Pointd的有2個默認參數的構造函數! " << this->a << " " << this->b << endl; } ~Point() { cout << "Point對象被析構了! "<<this->a << " " << this->b << " " << this->c << endl; } int getC() { return c; } private: int a; int b; int c; }; int run() { Point aa(1, 2); cout << aa.getC() << endl; //c的值為垃圾值,因為匿名對象被創建有立即析構了
//就算用不析構的方式,也是垃圾值,因為c是不同對象中的元素
//在2個參數的構造函數中,沒有顯式初始化c,不能通過構造其他對象而在本構造對象中訪問未初始化的數據 return 0; } int main() { run(); cout << "hello world!\n"; return 0; }