程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ 構造函數和析構函數

C++ 構造函數和析構函數

編輯:C++入門知識

C++ 構造函數和析構函數


構造函數:

作用:

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、為什麼要把析構函數定義為虛函數?
因為:虛函數是為了支持多態,。。。之後補充

遇到的問題

    #include   
    using 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時,需要用到析構函數。鏈接時,系統就會找其實現。當發現沒實現時,而報錯。

所以,我們在聲明了函數就要記得實現,尤其是構造函數和析構函數,拷貝構造函數、賦值運算符。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved