文章目錄
- 2.2解構函式
- 2.3拷貝建構函式
- 4.1代碼
- 4.2運行結果
- 5.1代碼
- 5.2運行結果
- 5.3說明
1.參考文獻
參考1:
C++繼承中建構函式、解構函式調用順序及虛函數的動態綁定
參考2: 建構函式、拷貝建構函式和解構函式的的調用時刻及調用順序
參考3: C++建構函式與解構函式的調用順序
2.建構函式、解構函式與拷貝建構函式介紹2.1建構函式
- 建構函式不能有傳回值
- 預設建構函式時,系統將自動調用該預設建構函式初始化對象,預設建構函式會將所有資料成員都初始化為零或空
- 建立一個對象時,系統自動調用建構函式
2.2解構函式
- 解構函式沒有參數,也沒有傳回值。不能重載,也就是說,一個類中只可能定義一個解構函式
- 如果一個類中沒有定義解構函式,系統也會自動產生一個預設的解構函式,為空白函數,什麼都不做
- 調用條件:1.在函數體內定義的對象,當函數執行結束時,該對象所在類的解構函式會被自動調用;2.用new運算子動態構建的對象,在使用delete運算子釋放它時。
2.3拷貝建構函式
拷貝建構函式實際上也是建構函式,具有一般建構函式的所有特性,其名字也與所屬類名相同。拷貝建構函式中只有一個參數,這個參數是對某個同類對象的引用。它在三種情況下被調用:
- 用類的一個已知的對象去初始化該類的另一個對象時;
- 函數的形參是類的對象,調用函數進行形參和實參的結合時;
- 函數的傳回值是類的對象,函數執行完返回調用者。
3.建構函式與解構函式的調用順序對象是由“底層向上”開始構造的,當建立一個對象時,首先調用基類的建構函式,然後調用下一個衍生類別的建構函式,依次類推,直至到達衍生類別次數最多的派生次數最多的類的建構函式為止。因為,建構函式一開始構造時,總是要調用它的基類的建構函式,然後才開始執行其建構函式體,調用直接基類建構函式時,如果無專門說明,就調用直接基類的預設建構函式。在對象析構時,其順序正好相反。4.執行個體14.1代碼
#include<iostream>using namespace std;class point{private:int x,y;//資料成員public:point(int xx=0,int yy=0)//建構函式{x=xx;y=yy;cout<<"建構函式被調用"<<endl;}point(point &p);//拷貝建構函式,參數是對象的引用~point(){cout<<"解構函式被調用"<<endl;}int get_x(){return x;}//方法int get_y(){return y;}};point::point(point &p){x=p.x;//將對象p的變相賦值給當前成員變數。y=p.y;cout<<"拷貝建構函式被調用"<<endl;}void f(point p){cout<<p.get_x()<<""<<p.get_y()<<endl;}point g()//傳回型別是point{point a(7,33);return a;}void main(){point a(15,22);point b(a);//構造一個對象,使用拷貝建構函式。cout<<b.get_x()<<""<<b.get_y()<<endl;f(b);b=g();cout<<b.get_x()<<""<<b.get_y()<<endl;}4.2運行結果4.3結果解析建構函式被調用 //point a(15,22);
拷貝建構函式被調用 //point b(a);拷貝建構函式的第一種調用情況:
用類的一個已知的對象去初始化該類的另一個對象時
15 22 //cout<<b.get_x()<<" "<<b.get_y()<<endl;拷貝建構函式被調用 //f(b);拷貝建構函式的第二種調用情況:
函數的形參是類的對象,調用函數進行形參和實參的結合時
15 22 //void f(point p)函數輸出對象b的成員
解構函式被調用 //f(b);解構函式的第一種調用情況:
在函數體內定義的對象,當函數執行結束時,該對象所在類的解構函式會被自動調用
建構函式被調用 //b=g();的函數體內point a(7,33);建立對象a
拷貝建構函式被調用 //b=g();拷貝建構函式的第三種調用情況,拷貝a的值賦給b:
函數的傳回值是類的對象,函數執行完返回調用者
解構函式被調用 //拷貝建構函式對應的解構函式
解構函式被調用 //b=g();的函數體內對象a析構
7 33
解構函式被調用 //主函數體b對象的析構
解構函式被調用 //主函數體a對象的析構5.執行個體25.1代碼
#include <iostream>using namespace std;//基類class CPerson{char *name; //姓名int age; //年齡char *add; //地址public:CPerson(){cout<<"constructor - CPerson! "<<endl;}~CPerson(){cout<<"deconstructor - CPerson! "<<endl;}};//衍生類別(學生類)class CStudent : public CPerson{char *depart; //學生所在的系int grade; //年級public:CStudent(){cout<<"constructor - CStudent! "<<endl;}~CStudent(){cout<<"deconstructor - CStudent! "<<endl;}};//衍生類別(教師類)//class CTeacher : public CPerson//繼承CPerson類,兩層結構class CTeacher : public CStudent//繼承CStudent類,三層結構{char *major; //教師專業float salary; //教師的工資public:CTeacher(){cout<<"constructor - CTeacher! "<<endl;}~CTeacher(){cout<<"deconstructor - CTeacher! "<<endl;}};//實驗主程式void main(){//CPerson person;//CStudent student;CTeacher teacher;}5.2運行結果5.3說明在執行個體2中,CPerson是CStudent的父類,而CStudent又是CTeacher的父類,那麼在建立CTeacher對象的時候,首先調用基類也就是CPerson的建構函式,然後按照層級,一層一層下來。