天天看點

面向對象程式設計,類與對象的詳細解答(構造、析構函數)一、面向對象程式設計二、類和對象三、類的定義與執行個體化四、構造函數與初始化清單五、對象建立過程六、類的聲明與實作分開六、析構函數六、預設的析構函數,構造函數

一、面向對象程式設計

​ 面向過程程式設計:關注于解決問題的方法、步驟。

​ 面向對象程式設計:關注于誰能解決問題(類),以及解決問題需要的資料(成員變量),以及解決問題需要的技能(成員函數)。

​ 抽象:想象出一個能解決問題的對象(觀察、想象),分析出解決問題需要的屬性(成員變量)和行為(成員函數)。

​ 封裝:把抽象的結果分裝成類(資料類型),并設定上相應的通路權限。

​ 使用封裝的類執行個體化對象,調用對象的成員函數與成員變量互相作用達到解決問題的目的。

​ 繼承:在解決問題之前,先尋找有沒有能解決部分問題的類,如果有則把舊的類繼承并再拓展,然後縮短解決問題的時間、降低解決問題的難度。

​ 多态:對象的多種形态,當對象發出一條指令,對象會根據自身的情況作出獨特的響應。

二、類和對象

​ 1、把抽象結果封裝成一個資料類型(結構、類)

​ 2、類就是一種資料類型

​ 簡單類型:隻能表示一個變量,C/C++内建資料類型

​ 數組類型:類型相同的多個變量

​ 結構類型:不同類型的多個變量

​ 類類型:不同類型的多個變量、函數

​ 3、對象:類這種資料類型建立出來的執行個體,相當于結構變量

三、類的定義與執行個體化

1、類的一般形式

class 類名:繼承方式 父類名
{
通路限定符:
    成員變量;
通路限定符:
    //構造函數
    類名(形參清單)
	{
    	函數體;
	}
    //成員函數;
    傳回值 函數名(形參清單)
	{
    	函數體;
    	return val;
	}
};
           

2、通路限定符

​ public:共有成員,可以在任何位置通路。

​ protected:受保護成員,隻能在自己的成員函數中和子類的成員函數中通路。

​ private:私有成員,隻能在自己的成員函數通路。

注意:在class中成員的預設是private,在struct中成員預設是public。

​ 一般把成員變量設定為private,把成員函數設定為public。

3、對象的建立方法

​ 在棧上建立方法

​ 類名 對象;

​ 類名 對象數組名[對象數量];

​ 在堆上建立

​ 類名* 對象指針 = new 類名;

​ 類名* 對象指針 = new 類名[對象數量];

四、構造函數與初始化清單

1、什麼是構造函數

​ 對象建立時自動調用的函數叫構造函數,負責完成一些準備工作。

2、無參構造

​ 一個類中至少要有一個構造函數,如果不顯示實作,編譯器則自動生成一個沒有參數的構造函數,也叫無參構造。

​ 如果顯式實作了構造函數,則無參構造不再生成,為了避免出錯,最好在顯式實作一個什麼都不做的無參構造。

3、有參構造

​ 建立對象可以附帶一些資料給構造函數,用于初始化成員變量,這樣就必須顯式實作帶參數的構造函數,構造函數的參數就是建立對象時傳遞的資料。

注意:可以給有參構造設定預設參數,這樣可以達到無參構造的效果。

​ 類名 對象(實參);

​ 類名* 對象指針 = new 類名(實參);

4、單參構造

​ 如果構造函數隻有一個,如此參數的類型與類型之間有類型提升的特性。

​ 如果不想有類型提升的功能,可以在單參構造前加explicit關鍵字,禁止單參構造的類型提升。

class Test
{
    public:
    Test(int n)
    {
        
    }
};
Test t = 10;//自動調用單參構造而不會出錯。
           

5、初始化清單

構造函數(參數):成員1(參數1),成員2(參數2)//初始化清單
{
    
}
           

初始化清單就是一種給類的成員變量初始化的一種文法格式。

特點:

​ 1、可以區分相同的參數和成員變量。

​ 2、可以給類類型的成員變量或構造函數傳遞參數。

​ 3、還可以給父類的構造函數傳遞參數

​ 4、常屬性的成員隻能在初始化清單中指派

五、對象建立過程

  1. 配置設定類對象所需要的記憶體空間,無論棧或堆
  2. 傳遞實參調用構造函數,完成如下任務:
    1. 執行初始化清單
    2. 根據繼承表繼承順序調用父類構造函數
    3. 根據成員變量的定義順序調用成員變量的構造函數
    4. 執行構造函數中的代碼

六、類的聲明與實作分開

1、在頭檔案中聲明類

class 類名:繼承方式 父類
{
    成員變量;
    ...
public:
    類名(形參清單);
    傳回值 成員函數(形參清單);
    ...
}
           

2、在源檔案中實作類的成員函數

#include "聲明類的頭檔案"
類名::類名(形參清單)
{
}
傳回值 類名::成員函數(形參清單)
{
    函數體;
    return val;
}
           

3、使用類隻需要包含類的頭檔案,然後使用者與類的源檔案目标檔案一起合并即可。

注意:如果類中的内容不多,在頭檔案中全部實作。

六、析構函數

1、什麼是析構函數

​ 與構造函數一樣也是一種特殊的成員函數,它會在對象釋放的時候自動調用,負責一些收尾工作,如:儲存資料、釋放資源等。

2、函數格式

~類名(void)
{
    
}
           

3、析構函數的任務

​ 負責釋放在構造函數中擷取到的所有資源。

​ 執行過程:

​ 1、先執行析構函數本身代碼

​ 2、調用成員變量的析構函數

​ 3、調用父類的析構函數

  • 注意:析構函數與構造函數的執行順序剛好相反
#include <iostream>
using namespace std;

class Test
{
public:
	Test(void)
	{
		cout<<"我是構造函數"<<endl;
	}
	~Test(void)
	{
		cout<<"我是析構函數"<<endl;
	}
};

void func(void)
{
	Test* t = new Test;
	cout<<"-------"<<endl;
	delete t;
}
int main(int argc,const char* argv[])
{
	int n=3;
	while(n--)
	func();
}
           

六、預設的析構函數,構造函數

1、 定義

在設計一個類時,如果沒有顯示實作構造函數與析構函數,編譯器 會自動生成它們,也叫預設的構造和析構函數。

但生成的并不是真正文法意義上的函數,而是功能意義上的函數。

編譯器做為可執行指令的生成着,它有能力直接生成某些功能的二進制指令,不需要借助語言上的函數完成某些任務。

2、 什麼時候需要顯示實作構造函數

  1. 有成員需要初始化
  2. 需要一些參數做一些準備工作
  3. 需要在對象使用之前準備一些資源.如:申請一些堆記憶體

3.、什麼時候需要顯示實作析構函數

預設的析構函數會自動釋放編譯器能看得到的所有資源。如:成員變量,類成員,父類

  1. 儲存一些資料
  2. 成員變量中有指針,且指向堆記憶體。

繼續閱讀