9——對象的建立和撤銷,構造函數和析構函數

一是構造函數在對象建立時自動調用,用以完成對象成員變量等的初始化及其餘操做(如爲指針成員動態申請內存空間等); 若是程序員沒有顯式的定義它,系統會提供一個默認的構造函數。
另外一個是析構函數,在對象撤銷時自動調用,用以執行一些清理任務,如釋放成員函數中動態申請的內存等。 若是程序員沒有顯式的定義它系統也會提供一個默認的析構函數。 
 
 當對象被建立時,構造函數自動被調用。
        構造函數有一些獨特的地方: 函數的名字與類名相同,沒有返回類型和返回值,即便是void也不能有
         1> 其主要工做有: 給對象一個標識符。 
         2> 爲對象數據成員開闢內存空間。 
          3> 完成對象數據成員的初始化函數體內的工做,由程序員完成)。
上述3點也說明了構造函數的執行順序, 在執行函數體以前,構造函數已經爲對象的數據成員開闢了內存空間,這時, 在函數體內對數據成員的初始化即是瓜熟蒂落了。 備註代碼給出了point類的顯式構造函數 。
 
class point 
{ 
private:    
    int xPos;     
    int yPos; public:     
    point(); 
}; 
point::point() 
{     
    xPos = 0;     
    yPos = 0; 
} 
 
構造函數能夠有參數:
 編譯器自動生成的缺省(默認)構造函數是無參的,實際上, 構造函數能夠接收參數,在對象建立時提供更大的自由度,以下列代碼
一旦用戶定義了構造函數,系統便再也不提供默認構造函數。 跟蹤執行,理解構造函數的執行順序。
 
//point.h
#include <iostream> 
using namespace std; 
class point //point類定義,在定義同時實現其成員函數 
{ 
private: //私有成員,分別表明x軸和y軸座標     
        int xPos;     
        int yPos; 
public:     
        point(int x, int y) //有參構造函數     
        {         
                cout << "對象建立時構造函數被自動調用" << endl;         
                xPos = x;         yPos = y;     
        }     
        void print() //輸出信息     
        {         
                cout << "xPos: " << xPos << ",yPos: " << yPos << endl;     
        } 
}; 

#include "point.h" 
int main() 
{ 
        //    point pt0;//錯誤的調用,由於咱們已經顯示的定義了一個帶參數的構造函數 
        //    pt0.print();//輸出pt0的信息     
        point pt1(3, 4);    //調用有參構造函數聲明point類變量(類對象)pt1                         	pt1.print();        //輸出pt1的信息     
        return 0;
 }  

 

構造函數可以進行重載:
一旦程序員 爲一個類定義了構造函數編譯器便不會爲類 自動生成缺省構造函數
所以, 若是還想使用無參的構造函數,如「point pt1;」 的形式必須在類定義中顯式定義一個無參構造函數。 這樣,構造函數就會出現兩個,會不會有問題呢?不會,構造函數支持重載,在建立對象時,根據傳遞的具體參數決定採用哪一個構造函數。
 

例1ios

#include <iostream>
using namespace std;

class Point
{
public:
	Point()//構造函數可以進行重載
	{
        	cout << "Point()" << endl;
	} 

	Point(int ix, int iy)
	{
        	cout << "Point(int,int)" << endl;

        	_ix = ix;
        	_iy = iy;
	}

	void print()
	{

		cout << "(" << _ix<< "," << _iy<< ")" << endl;
	}

private:
        int _ix;
        int _iy;
};

int main(void)
{
        Point p1;//調用默認構造函數
        p1.print();
 
        Point p2(3, 4);
        p2.print();

        return 0;
}
例2
//point1.h
#include <iostream> 
using namespace std; 
class point //point類定義,在定義同時實現其成員函數 
{ 
public:     
        point(int x, int y)//有參構造函數     
        {         
                cout << "有參構造函數的調用" << endl;         
                xPos = x;         
                yPos = y;     
        }     
        point() //無參構造函數     
        {         
                cout << "無參構造函數的調用" << endl;         
                xPos = 0;         
                yPos = 0;            
        }     
        void print()//輸出信息     
        {         
                cout << "xPos: " << xPos << ",yPos: " << yPos << endl;     
        } 
private: //私有成員,分泌誒表明x軸和y軸座標     
        int xPos;     
        int yPos; 
};
#include "point1.h" 
int main() 
{     
        point pt1(3, 4);    //調用有參構造函數聲明point類變量(類對象)pt1                         pt1.print();        //輸出pt1的信息     
        point pt2;            //調用無參構造函數聲明point類變量(類對象)pt2                         pt2.print();        //輸出pt2的信息     
        return 0;
}  

  

------------------
構造函數容許按參數缺省方式調用
上例中的構造函數能夠做以下定義:
point(int x=0,int y=0) 
{ 
        cout<<"對象建立時構造函數被自動調用"<<endl; 
        xPos=x; 
        yPos=y; 
} 
此時,可在建立對象時省略參數,下列語句都是合法的: 
       
 	point pt;    //x和y都採用默認值0 
        point pt(3);    //x爲3,y採用默認值0 
        point pt(3,4);//x爲3,y爲4,兩個參數都不採用默認值
 
初始化表達式1
        除了在構造函數體 初始化數據成員 外,還能夠 經過成員初始化表達式來完成
        成員初始化表可用於初始化類的任意數據成員(後面要介紹的static數據成員除外),
         該表達式逗號分隔的數據成員表組成初值放在一對圓括號中
 
        只要 將成員初始化表達式放在構造函數的頭和體之間並用冒號將其與構造函數的頭分隔開,即可實現數據成員表中元素的初始化 
 
point(int x,int y)
{ 
        cout<<"有參構造函數的調用"<<endl; 
        xPos=x; 
        yPos=y; 
} 
//等價於: 
point(int x,int y)
:xPos(x)
,yPos(y) 
{     
        cout<<"有參構造函數的調用"<<endl; 
}
 
--------------------------
初始化表達式2 
        每一個成員在初始化表中只能出現一次 
        初始化的順序不是由成員變量在初始化表中的順序決定的
         而是由成員變量在類中被聲明時的順序決定的。(即在private中聲明的順序)
        理解這一點有助於避免意想不到的錯誤。
 
//point.h
#include <iostream> 
using namespace std; 
class point 
{ 
private:     
        int yPos;    //先定義     
        int xPos;    //後定義 
public:     
        point(int x)
        :xPos(x)
        , yPos(xPos) //初始化表取決於成員聲明的順序     
        //若是換成
        //:yPos(y)
        //,x(yPos)//這樣的話,x先初始化,可是這時yPos尚未初始化,x就是不肯定的值了
        {     
        }     
        void print()     
        {         
                cout << "xPos: " << xPos << ", yPos: " << yPos << endl;     
        } 
}; 
#include "point.h" 
int main() 
{     
        point pt1(3);        //調用有參構造函數聲明變量pt1     
        pt1.print();         
        return 0; 
}  

  

 
例子:
#include <iostream>
using namespace std;

class Point
{
public:
#if 0
    Point()//構造函數可以進行重載
    {
        cout << "Point()" << endl;
    }
#endif
 
    Point(int ix, int iy)
    : _ix(ix)//初始化列表
    , _iy(iy)
    {
        cout << "Point(int,int)" << endl;
        //_ix = ix;//賦值
        //_iy = iy;
    }
    void print()
    {
        cout << "(" << _ix
             << "," << _iy
             << ")" << endl;
    }
private:
    int _ix;
    int _iy;
};
 
int main(void)
{
    Point p1;//調用默認構造函數
    p1.print();
 
    Point p3(5);
    p3.print();
 
    Point p2(3, 4);
    p2.print();
 
    return 0;
}
相關文章
相關標籤/搜索