1. 程式人生 > >C++:建構函式&解構函式

C++:建構函式&解構函式

建構函式:    
      C++類的目標之一是讓使用類物件就像使用標準型別一樣,事實上它並不能像初始化int型別那樣初始化類物件,也就是說,常規的初始化語法不適用於類物件。為此,C++提供了一個特殊的成員函式——類建構函式。它是一種特殊的類成員函式,在建立類物件時被呼叫。通常,建構函式用於初始化物件的成員。

規則
      ·建構函式的名稱和類名相同,通過函式過載,可以建立多個同名的建構函式
      ·建構函式沒有宣告型別。初始化與建構函式的引數列表相匹配。            
      ·如果不實現建構函式,編譯器會生成一個預設建構函式;如果自己實現,則編譯器不會生成。 

系統預設的建構函式:

  類名()
{
    
}

建立不同的建構函式,系統是以怎樣的方式呼叫的?

#include<iostream>

class CGoods
{
public:
	CGoods(const char* name, double price, int amount)//帶有三個引數的建構函式
	{
		std::cout << this << " :CGoods::CGoods(char*,float,int)" << std::endl;
		mname = new char[strlen(name) + 1]();
		strcpy(mname, name);
		mprice = price;
		mamount = amount;
	}

	CGoods(const char* name, double price)//帶有兩個引數的建構函式
	{
		std::cout << this << " :CGoods::CGoods(char*,float)" << std::endl;
		mname = new char[strlen(name) + 1]();
		strcpy(mname, name);
		mprice = price;
	}

	CGoods(int amount)//帶有一個整形引數的建構函式
	{
		std::cout << this << " :CGoods::CGoods(int)" << std::endl;
		mname = new char[1]();
		mamount = amount;
	}

	CGoods()//不帶引數的建構函式
	{
		std::cout << this << " :CGoods::CGoods()" << std::endl;
		mname = new char[1]();
	}
	
	~CGoods()
	{
		std::cout << this << " :CGoods::~CGoods()" << std::endl;
		delete[] mname;
	}

private:
	char*  mname;
	double mprice;
	int mamount;
};

int main()
{
	CGoods good1("car1", 10.1, 10);
	CGoods good2("car1", 15.1);
	CGoods good3(20);
	CGoods good4;

	return 0;
}

程式執行結果

 

結論
      呼叫建構函式時,系統會選擇函式形參列表與定義物件時的實參列表相匹配的那個建構函式進行呼叫。

物件的生成
         1)開闢記憶體    2)賦資源(記憶體空間進行初始化)

思考:建構函式能否手動呼叫物件? 
        不能手動呼叫物件,因為建構函式是生成物件的一環,無法使用物件來呼叫建構函式,在建構函式生成物件之前,物件是不存在的,就像父子,沒有父,便沒有子。即建構函式被用來建立物件,而不能通過物件來呼叫。

解構函式
       完成清理工作,物件生命週期結束時,程式自動呼叫一個特殊的類成員函式,即解構函式。解構函式名稱前面加個~,和建構函式一樣,解構函式沒有返回型別,也沒有引數。每個類只有一個解構函式。

系統預設的解構函式:   
        如果建構函式沒有使用new,只需編譯器生成一個什麼都不用做的解構函式即可。

  ~類名()
{
   
}

      如果建構函式使用new來分配記憶體,則必須使用delete提供的解構函式釋放這些記憶體。

 ~CGoods()
{
   delete[] mname;
   mname=NULL;
}

物件的銷燬:1)釋放資源   2)釋放空間

思考:解構函式能否手動呼叫物件? 
           可以手動呼叫物件。

注意:先構造的後析構,後構造的先析構。