1. 程式人生 > >C++入門筆記---定義構造器(建構函式)和析構器

C++入門筆記---定義構造器(建構函式)和析構器

回顧一下OOP技術的基礎:

-定義一個有屬性和方法的類(模板)

-為該類建立一個變數(實現)

但是面向物件過程可不只有這麼簡單,接下來我們更深一步的瞭解他。

1.建構函式(構造器)

首先就是構造器,他也是一種方法,並且每個類至少有一個構造器,如果在建立類的時候沒有定義構造器的話,編譯器會預設生成一個無引數的構造器,這個建構函式的作用是對例項化的物件進行初始化,構造器和通用的方法的區別:

  1. 構造器的名字必須和他所在的類的名字一樣
  2. 系統在建立某個類的例項的時候會第一時間呼叫這個類的構造器
  3. 構造器永遠不會返回任何值

建立構造器,需要先把這個函式的宣告加到類裡面去

class Car{
    Car(void);//因為構造器沒有任何返回值 所以也不用在Car前面加上一個void
};

注意大小寫和類名保持一致,在結束宣告之後開始定義構造器本身,也就是寫這個建構函式

Car::Car(void){//不用寫void Car::Car(void) 因為構造器會預設他沒有任何返回值 並且我們在類裡宣告這個函式的時候也沒有寫
    color = "WHITE";
    engine = "V8";
    wheel = 4;
    gas_tank = FULL_GAS;//FULL_GAS意為油缸是滿的 在真正實現這個函式的時候 可以對其進行巨集定義
}

 那麼我們就可以對這個類各種填東西,讓他看起來不那麼簡陋......如下,是我自己寫的一個簡單的類,例項化一個物件,以及呼叫物件的方法的一個小程式碼,當然這個程式碼雖然可以執行,但是有非常多的不足,只是在剛開始的時候拿來練練手罷了。

#include<iostream>
#define FULL_GAS 85

class Car{
	public:
		std::string color;
		std::string engine;
		unsigned int gas_tank;
		unsigned int wheel; 
		
		Car(void);//建構函式 
		void setColor(std::string col);//更改顏色 
		void setEngine(std::string eng);//更改引擎
		void setWheel(unsigned int whe);//更改輪子個數
		void fill_tank(int liter);//加油
		int running(void);//讓車跑起來 
		void warning(void);//油不夠的時候 進行警告 
		
};

Car::Car(void){
	color = "WHITE";
    engine = "V8";
    wheel = 4;
    gas_tank = FULL_GAS;
}

void Car::setColor(std::string col){
	color = col;
}

void Car::setEngine(std::string eng){
	engine = eng;
}

void Car::setWheel(unsigned int whe){
	wheel = whe;
}

void Car::fill_tank(int liter){
	gas_tank += liter;
}

int Car::running(void){
	char answer;//用於答覆是否需要加滿油 
	
	std::cout<<"我是一輛汽車,我正在以120的速度向前移動.........\n";
	gas_tank--;
	std::cout<<"當前還剩"<<100*gas_tank/FULL_GAS<<"%的油量";
	
	if(gas_tank<10){
		std::cout<<"是否需要加滿油再繼續行駛?(Y/N)\n";
		std::cin>>answer;
		if(answer=='y'||answer=='Y') fill_tank(FULL_GAS);
		if(gas_tank==0){
			std::cout<<"沒油了!\n";
			return 0;
		} 	
	}
	return 1;
}

void Car::warning(void){
	std::cout<<"WARNING!還剩"<<100*gas_tank/FULL_GAS<<"%油量!\n";
}
int main(){
	Car mycar;
	while(mycar.running()) ;
	return 0;
} 

執行結果:

構造物件陣列:之前講過陣列可以是任何一種資料型別,當然也包括物件。

Car mycar[10];
//呼叫的語法依舊是:mycar[x].running;

 注意:x代表著給定元素的下標,mycar這個數組裡每一個單元都儲存著一個Car類的例項化物件,這樣我們就可以造很多車了~~~

構造器總結:

  1. 每個類至少有一個構造器,如果你沒有在類裡定義一個構造器,編譯器就會使用如下語法替你定義一個空的構造器:ClassName::ClassName(){},其實除此之外編譯器還會替你建立一個副本構造器(CopyConstructor),所以構造器是很重要的,沒有他就不能例項化物件。
  2. 一個常見的做法就是在建立物件的時候做出一些事情(藉助建構函式),在物件創建出來以後用另一種方法做同樣或不同的事情,
Car mycar;//這個在例項化這個物件的時候 構造器已經把他初始化為白色 這樣該是最普遍的顏色
mycar.setColor("Yellow");//但是我不喜歡這種大眾的顏色 我想要改變一下 我想要與眾不同 那就可以根據自己的喜好來呼叫set函式更改顏色

析構器 

從前面的內容我們瞭解到,在建立物件的時候,系統都會自動呼叫一個特殊的方法,即構造器。相應的,在銷燬一個物件的時候,系統也會呼叫另外一個特殊的函式達到相應的效果,這就叫做析構器。一般來說構造器用來完成實現的初始化和準備工作(申請分配記憶體),那麼析構器用來完成時候所必須的清理工作(清理記憶體),在java裡有一個垃圾處理機制,所以在Java裡沒有析構器,但是c++裡必須有。構造器和析構器兩者相輔相成,有許多共同之處。首先,析構器有著和構造器/類一樣的名字,只不過前邊多了一個波浪符"~"字首。

class Car{
    Car(void);//構造器
    ~Car();//析構器
   };

注意: 

  1. 析構器也永遠不返回任何值,所以在宣告他的時候,像構造器一樣,前面不用加上void
  2. 析構器永遠是不帶引數的,你想象一下,你都準備銷燬這個物件了,這個物件已經沒用了,你還傳引數幹嘛....所以析構器的宣告永遠是這個格式:~ClassName();
  3. 一般來說析構器是可有可無的,但是構造器必須存在。雖然他可有可無,但是在比較複雜的類裡,析構器往往至關重要(可能會引起記憶體洩露),例如在某個類的構造器裡申請了一塊記憶體,我們就必須在析構器裡面釋放那塊記憶體。寫一個也不費事,不寫有風險,所以還是寫上比較好。

下面就用一個自己寫的例子來感受一下析構器裡面的內容應該怎麼去寫:

程式設計任務:從鍵盤輸入以段名言和一個作者 將這些內容寫入到指定檔案中去

//輸入一句名言和作者 將其寫入檔案中去 

#include<iostream>
#include<string>
#include<fstream>

class StoreQuote
{
public:
	std::string quote,speaker; 
	std::ofstream fileOutput;
	
	StoreQuote();//構造器 
	~StoreQuote();//析構器
	void inputQuote();
	void inputSpeaker();
	bool write();//將內容寫入檔案 
};

StoreQuote::StoreQuote(){
	fileOutput.open("E:\\test.txt",std::ios::app);//如果沒有改檔案的話 會新建一個 然後開啟方式是在檔案尾部追加	
}

StoreQuote::~StoreQuote(){
	fileOutput.close();//關閉檔案 在構造器裡申請開啟檔案 自然在呼叫結束後就要將其關閉 否則會記憶體洩漏 
} 

void StoreQuote::inputQuote(){
	std::getline(std::cin,quote);//前面講過不能用scanf 因為遇到空格就會停止 獲取一段字串 要用string類裡的getline函式來讀取一行 
}

void StoreQuote::inputSpeaker(){
	std::getline(std::cin,speaker);
}

bool StoreQuote::write(){
	if(fileOutput.is_open()){//fileOutput是ofstream類的一個例項化物件 這個類裡有is_open()方法,用來判斷目標檔案是否正常開啟 
		fileOutput<<quote<<"|"<<speaker<<"\n";//輸出流不再是我們平時認為的stdout(螢幕)了 已將變成fileOutput了 建構函式裡fileOutput指向E:\test文件 
		return true;
	}
	return false;
}

int main(){
	StoreQuote sq;
	
	std::cout<<"請輸入一句名言:\n";
	sq.inputQuote();
	
	std::cout<<"請輸入名言的作者:\n";
	sq.inputSpeaker();
	
	if(sq.write()) std::cout<<"成功寫入檔案!\n";
	else std::cout<<"寫入檔案失敗!\n";
	
	return 0;
} 

執行結果:

1.從鍵盤輸入,顯示成功寫入檔案,那就去E盤檢視一下

2.檢視E盤,存在test文件,開啟文件檢查內容是否被寫進去 

3.寫入成功 

 

 以上就是構造器和析構器的內容,關於析構器的內容,要好好看一下最後一個程式碼!