C++和java中建構函式與解構函式的調用順序

來源:互聯網
上載者:User
文章目錄
  • 2.2解構函式
  • 2.3拷貝建構函式
  • 4.1代碼
  • 4.2運行結果
  • 4.3結果解析
  • 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代碼View Code

#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代碼View Code

#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的建構函式,然後按照層級,一層一層下來。ps:2012-4-12

在java中,執行個體化一個子類的對象,首先會調用父類的無參建構函式。如果父類沒有顯式定義建構函式,那麼會調用預設建構函式,這個預設建構函式是由編譯器自動產生的。如果父類顯式定義了建構函式,那麼編譯器就不再為父類產生預設預設建構函式。

假設父類中定義了一個帶參數的建構函式,而沒有定義無參建構函式,這時候執行個體化一個子類的對象,就會出現編譯錯誤,因為子類首先要調用父類的無參建構函式,但是父類沒有顯式定義,編譯器又不為父類產生預設建構函式。這時候可以通過在父類中顯示定義無參建構函式來解決這個錯誤。

this()和super()都可以用來調用建構函式,而this()用於在同一個類內調用其他的建構函式,比如首先在Student類中定義了一個建構函式Student(name,age),又另外定義了一個建構函式Student(name,age,school),那麼在第二個建構函式中可以通過this(name,age)的形式來調用第一個建構函式,注意這裡this(name,age)必須寫在第二個建構函式的首行。而super用於從子類的構造方法中調用父類的構造方法。比如父類Person有建構函式Person(String name, int age),而子類有建構函式Student(String name, int age, String school, String grade),那麼就可以在子類建構函式中通過super(name,age)來調用父類建構函式。

建議:最好為每個類都顯示定義無參建構函式。

執行個體

Person類

View Code

public class Person {    private String name = "";    private int age = 0;    public Person() {        System.out.println("Person類無參數建構函式");    }    public Person(String name, int age) {        this.name = name;        this.age = age;        System.out.println("Person類帶2參數的建構函式");    }}

Student類

View Code

public class Student extends Person {    private String school;    private String grade;    public Student() {        System.out.println("Student類無參數的建構函式");    }    public Student(String name, int age, String school) {        super(name,age);        this.school=school;        System.out.println("Student類帶3參數的建構函式");    }    public Student(String name, int age, String school, String grade) {        this(name,age,school);        this.grade = grade;        System.out.println("Student類帶4參數的建構函式");    }}

Test類

View Code

public class Test {    public static void main(String[] args) {        System.out.println("無參數執行個體:");        Student st1 = new Student();        System.out.println("---------------------------");        System.out.println("3參數執行個體:");        Student st2 = new Student("zhangshan",25,"mit");        System.out.println("---------------------------");//        System.out.println("4參數執行個體:");        Student st3 = new Student("lisi", 24, "mit", "研究生");    }}

 執行個體運行結果:

無參數執行個體:
Person類無參數建構函式
Student類無參數的建構函式
---------------------------
3參數執行個體:
Person類帶2參數的建構函式
Student類帶3參數的建構函式
---------------------------
4參數執行個體:
Person類帶2參數的建構函式
Student類帶3參數的建構函式
Student類帶4參數的建構函式

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.