C++中多態(tài)使用詳細(xì)講解-創(chuàng)新互聯(lián)

大家都知道多態(tài)是面向?qū)ο缶幊痰囊粋€(gè)特性,簡(jiǎn)單點(diǎn)說:“一個(gè)接口,多種實(shí)現(xiàn)”,就是同一種事物表現(xiàn)出的多種形態(tài)。所有的面向?qū)ο缶幊痰恼Z(yǔ)言都有以下三種特性:繼承、封裝、多態(tài)。接下來我們要詳細(xì)的聊一聊C++中的多態(tài)是如何應(yīng)用的。

創(chuàng)新互聯(lián)長(zhǎng)期為上1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為曾都企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì),曾都網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。1.定義
  • 多態(tài)按字面的意思就是多種形態(tài)。當(dāng)類之間存在層次結(jié)構(gòu),并且類之間是通過繼承關(guān)聯(lián)時(shí),就會(huì)用到多態(tài)。C++ 多態(tài)意味著調(diào)用成員函數(shù)時(shí),會(huì)根據(jù)調(diào)用函數(shù)的對(duì)象的類型來執(zhí)行不同的函數(shù)。
  • 多態(tài)就是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力,指的就是行為的多態(tài)。比如動(dòng)物的爬行行為,小狗老虎,兔子它們各自的爬行方式是不同的,再比如草本植物都有自己的藥物功能,他們所對(duì)應(yīng)的藥物功能不一樣。
  • 其實(shí)多態(tài)就是同一個(gè)接口,使用不同的實(shí)例而執(zhí)行不同操作,比如我們?nèi)祟愂且粋€(gè)基類,程序員和會(huì)計(jì)是兩個(gè)不同的子類,他們都繼承了人類的吃、喝、學(xué)習(xí)、工作等等很多的能力,但是程序員在繼承基類的基礎(chǔ)上,又學(xué)會(huì)了敲代碼;會(huì)計(jì)學(xué)會(huì)了做賬單。他們產(chǎn)生的效果也是不同,程序員寫出了服務(wù)軟件給我們生活帶來了許多的方便,比如我們可以玩手機(jī)、網(wǎng)上購(gòu)物等等。會(huì)計(jì)可以幫我們公司算賬,計(jì)算我們每個(gè)人的工資,讓我們勞有所得,每個(gè)人都可以拿到自己的勞動(dòng)成果。

我們來看下面一個(gè)例子:

#includeusing namespace std;
 
class Shape {protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      { width = a;
         height = b;
      }
      virtual int area() // virtual是用來定義虛函數(shù)的,是C++繼承里不可缺少的關(guān)鍵字,如果不用它,那么我們就不會(huì)達(dá)到多態(tài)的效果,我們調(diào)用的依然是基類的方法。
      { cout<< "Parent class area :"<public:
      Rectangle( int a=0, int b=0):Shape(a, b) {}
      int area ()
      { cout<< "Rectangle class area :"<public:
      Triangle( int a=0, int b=0):Shape(a, b) {}
      int area ()
      { cout<< "Triangle class area :"<Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);
 
   // 存儲(chǔ)矩形的地址
   shape = &rec;
   // 調(diào)用矩形的求面積函數(shù) area
   shape->area();
 
   // 存儲(chǔ)三角形的地址
   shape = &tri;
   // 調(diào)用三角形的求面積函數(shù) area
   shape->area();
   
   return 0;
}
2.作用
  • 提高了代碼的維護(hù)性(繼承保證)
  • 提高了代碼的擴(kuò)展性(由多態(tài)保證)
  • 把不同的子類對(duì)象都當(dāng)作父類來看,可以屏蔽不同子類對(duì)象之間的差異,寫出通用的代碼,做出通用的編程,以適應(yīng)需求的不斷變化
3.使用格式

多態(tài)的定義格式:就是父類的引用變量指向子類對(duì)象

父類類型 變量名 = new 子類類型();

變量名.方法名();

4.多態(tài)存在的必要條件
  • 繼承
  • 重寫
  • 父類引用指向子類對(duì)象:Parent p = new Child(); 父類做形參,子類做實(shí)參
5.虛函數(shù)和純虛函數(shù)

虛函數(shù)是C++類繼承中必不可少的概念,我們要學(xué)好C++類的使用,就必須深刻的掌握虛函數(shù)

5.1 虛函數(shù)

虛函數(shù) 是在基類中使用關(guān)鍵字 virtual 聲明的函數(shù)。在派生類中重新定義基類中定義的虛函數(shù)時(shí),會(huì)告訴編譯器不要靜態(tài)鏈接到該函數(shù)。

我們想要的是在程序中任意點(diǎn)可以根據(jù)所調(diào)用的對(duì)象類型來選擇調(diào)用的函數(shù),這種操作被稱為動(dòng)態(tài)鏈接,或后期綁定。

5.2 純虛函數(shù)

您可能想要在基類中定義虛函數(shù),以便在派生類中重新定義該函數(shù)更好地適用于對(duì)象,但是您在基類中又不能對(duì)虛函數(shù)給出有意義的實(shí)現(xiàn),這個(gè)時(shí)候就會(huì)用到純虛函數(shù)。

我們可以把基類中的虛函數(shù) area() 改寫如下:

class Shape {protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      { width = a;
         height = b;
      }
      // pure virtual function
      virtual int area() = 0;
};

= 0 告訴編譯器,函數(shù)沒有主體,上面的虛函數(shù)是純虛函數(shù)。

5.3 抽象類

當(dāng)一個(gè)類中存在了純虛函數(shù),那么這個(gè)類就被稱做抽象類

抽象類特點(diǎn):

  • 抽象類無法進(jìn)行實(shí)例化
  • 如果抽象類的子類沒有重寫純虛函數(shù),那么該子類也無法進(jìn)行實(shí)例化
5.4 純虛析構(gòu)和虛析構(gòu)函數(shù)
class Animal
{public:
	Animal()
	{cout<< "調(diào)用Animal的構(gòu)造函數(shù)"<< endl;
	}
	virtual void speak() = 0;
 
	~Animal()
	{cout<< "調(diào)用Animal 的析構(gòu)函數(shù)"<< endl;
	}
};
{cout<< "調(diào)用Animal的析構(gòu)函數(shù)"<< endl;	
}
class Cat :public Animal
{public:
	Cat(string name)
	{cout<< "調(diào)用Cat的構(gòu)造函數(shù)"<< endl;
		_name = new string(name);
	}
	virtual void speak()
	{cout<< *_name<<"貓會(huì)說話"<< endl;
	}
	string* _name;
	~Cat()
	{cout<< "調(diào)用Cat的析構(gòu)函數(shù)"<< endl;
		if (_name != NULL)
		{	delete _name;
		}
	}
};
void test()
{Animal* c = new Cat("Tom");
	c->speak();
	delete c;
}
int main()
{test();
	return 0;
}
// 輸出結(jié)果:
調(diào)用Animal的構(gòu)造函數(shù)
調(diào)用Cat的構(gòu)造函數(shù)
Tom貓會(huì)說話
調(diào)用Animal的析構(gòu)函數(shù)

我們發(fā)現(xiàn)當(dāng)刪除c對(duì)象時(shí),沒有調(diào)用子類中的析構(gòu)函數(shù),而子類中又申請(qǐng)了堆上的空間,那么這樣就會(huì)造成內(nèi)存泄漏。

那么我們?nèi)绾伪WC調(diào)用子類中的析構(gòu)函數(shù)呢?

這里我們就需要在父類的析構(gòu)函數(shù)前面加上virtual來修飾,將父類析構(gòu)函數(shù)做如下修改

//虛析構(gòu)和純虛析構(gòu)都需要代碼的實(shí)現(xiàn)
    virtual	~Animal()
	{cout<< "調(diào)用Animal的析構(gòu)函數(shù)"<< endl;
	}
// 輸出結(jié)果:
調(diào)用Animal的構(gòu)造函數(shù)
調(diào)用Cat的構(gòu)造函數(shù)
Tom貓會(huì)說話
調(diào)用Cat的析構(gòu)函數(shù)
調(diào)用Animal的析構(gòu)函數(shù)

上面我們使用的是虛析構(gòu)函數(shù)來幫助我們解決內(nèi)存泄漏的問題,這里我們也可以使用純析構(gòu)函數(shù)來幫助我們,將父類的析構(gòu)函數(shù)改成:

virtual ~Animal() = 0;

我們這樣寫,程序會(huì)報(bào)錯(cuò),原因是我們沒有定義父類中的純虛析構(gòu)函數(shù),加上定義

Animal::~Animal()
{cout<< "調(diào)用Animal的析構(gòu)函數(shù)"<< endl;	
}

當(dāng)在類外實(shí)現(xiàn)了純虛析構(gòu)的實(shí)現(xiàn),編譯器就不再會(huì)報(bào)錯(cuò)

總結(jié):

  • 純虛析構(gòu)函數(shù)和虛析構(gòu)函數(shù)的共性:

    • 可以解決父類指針釋放子類對(duì)象不干凈的問題
    • 都需要具體的代碼實(shí)現(xiàn)
  • 純虛析構(gòu)函數(shù)和虛析構(gòu)函數(shù)的不同:

    • 如果一個(gè)類中存在純虛析構(gòu),這個(gè)類處于抽象類,不能進(jìn)行實(shí)例化
    • 如果是虛析構(gòu),仍可以進(jìn)行實(shí)例化

**注:**如果子類中沒有堆區(qū)的數(shù)據(jù),可以不用寫純虛析構(gòu)或者虛析構(gòu)

6.多態(tài)的底層原理
  • 有繼承關(guān)系

  • 子類要重寫父類中的虛函數(shù)

    有虛函數(shù)的類中會(huì)產(chǎn)生一個(gè)vfptr的指針和一個(gè)名為vftable的作用域,這個(gè)指針指向這個(gè)作用域,而在這個(gè)作用域中存在著被virtual修飾的函數(shù)的地址,如果沒有重寫父類中的虛函數(shù),那么在子類將繼承父類中的vftable,那么在調(diào)用speak函數(shù)時(shí),永遠(yuǎn)調(diào)用的是父類中實(shí)現(xiàn)的函數(shù)。

7.多態(tài)的特點(diǎn) 7.1 多態(tài)中,編譯看左邊(靜態(tài)綁定),運(yùn)行看右邊(動(dòng)態(tài)綁定)
  • 靜態(tài)綁定

    在編譯階段能夠確定方法在內(nèi)存什么位置的就叫靜態(tài)綁定,當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法,如果沒有,則編譯不通過;如果有,編譯通過。

  • 動(dòng)態(tài)綁定

    在運(yùn)行階段,父類對(duì)象類型在堆內(nèi)存中創(chuàng)建的實(shí)際對(duì)象是子類對(duì)象,根據(jù)內(nèi)存中真實(shí)的對(duì)象引用重新去給父類的方法表索引項(xiàng)賦值,這種通過程序運(yùn)行過程動(dòng)態(tài)創(chuàng)建對(duì)象方法表的定位方法的方式,一般稱之為動(dòng)態(tài)綁定。

7.2 向上轉(zhuǎn)型和向下轉(zhuǎn)型
  • 向上轉(zhuǎn)型

    子類引用的對(duì)象轉(zhuǎn)換為父類類型稱為向上轉(zhuǎn)型。就是是將子類對(duì)象看成父類對(duì)象。此處父類對(duì)象可以是接口。

  • 向下轉(zhuǎn)型:把父類對(duì)象轉(zhuǎn)為子類對(duì)象。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站名稱:C++中多態(tài)使用詳細(xì)講解-創(chuàng)新互聯(lián)
文章鏈接:http://www.muchs.cn/article32/dcdosc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、網(wǎng)站導(dǎo)航、軟件開發(fā)、定制開發(fā)、定制網(wǎng)站、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)