天天看點

c++之多态一、多态性的概念二、利用虛函數實作動态多态性

一、多态性的概念

多态性是面向對象程式設計的一個重要特征。如果一個語言隻支援類而不支援多态,是不能稱為面向對象語言的,隻能說是基于對象的,如Visual Bsaic。c++支援多态性,利用多态性可以設計和實作一個易于擴充的系統。

c++中這樣描述多态:向不同的對象發送同一個資訊,不同的對象在收到時會産生不同的行為。

所謂消息,就是調用函數,不同的行為,就是不同的實作,即執行不同的函數。

在c++中,多态的表現形式之一是:具有不同功能的函數可以用同一個函數名,這樣就可以實作用一個函數名調用不同内容的函數。

從系統的角度來看,多态分為兩類:靜态多态性和動态多态性。

靜态多态性是通過函數重載實作的。由函數重載和運算符重載(運算符重載實質上也是函數重載)形成的多态性屬于靜态多态性,要求在程式編譯時就知道調用函數的全部資訊,是以在程式編譯時就能決定要調用哪個函數,靜态多态性又稱吧編譯時多态性。

動态多态性的特點是:不在編譯時确定調用哪個函數,而是在程式運作過程中才動态地确定操作所針對的對象,又稱為運作時多态。

動态多态性時通過虛函數實作的。

二、利用虛函數實作動态多态性

1.虛函數的作用

所謂虛函數,就是在基類聲明函數時虛拟的,并不是實際存在的函數,然後在派生類中才正式定義此函數。

虛函數的作用時允許在派生類中重新定義與基類同名的函數,并且可以通過基類指針或者引用來通路基類和派生類的同名成員函數。

注意:

由虛函數實作的多态功能就是,同一類簇中不同類的對象,對同一函數調用作出不同的響應。

以前介紹的函數重載處理的是同一層次上的同名問題,而虛函數處理的是不同派生層次上的問題,前者是橫向重載,後者可以了解為縱向重載。

2.在什麼情況下應當聲明虛函數

是以虛函數使,有兩點要注意:

1.隻能用virtual聲明類的成員函數,而不能将類外的普通函數聲明為虛函數。

2.一個函數被聲明為虛函數後,不能再作為非虛函數。.

在什麼情況下應當聲明虛函數:

1.成員函數在類的繼承後,功能可能改變,則聲明為虛函數。

2.考慮對成員函數的調用時通過對象名,還是通過指針或者引用,如果時通過指針或者引用,則聲明為虛函數。

3.有時,在定義虛函數時,并不定義其函數體,即函數體是空的。它的作用隻是定義了一個虛函數,具體功能留給派生類添加。

3.虛析構函數

我們知道當派生類的對象從記憶體中撤銷時一般先調用派生類的析構函數,然後再調用基類的析構函數。但是,如果1.用new運算符建立了臨時對象,2.若基類中有析構函數,并且3.定義了指向該基類的指針變量。再程式用帶指針參數的delete運算符撤銷對象時,會發生一個情況:系統自會調用基類的構造函數,而不執行派生類的析構函數。

point *p=new cicle;
delete p;
//不會調用派生類的析構,隻會調用基類的析構函數。
           

如果希望能執行circle的析構函數,可以i将基類的析構函數聲明為虛析構函數。

注意:

1.如果将基類的析構函數聲明為虛構函數時,由該基類所派生的是以派生類的析構函數也都自動稱為虛函數,即使派生類的析構函數與基類的析構函數不同名。

2.構造函數不能說明為虛構函數。因為再執行構造函數時類對象還沒有完成建立過程,當然談不上把函數與類對象的綁定。

三、純虛函數與抽象類

1.純虛函數

純虛函數的一般形式:

virtual 函數類型 函數名(參數清單)=0;

注意:

(1).純虛函數沒有函數體

(2).最後面的’=0‘并不表示函數傳回值為0,它隻其形式上的作用,告訴編譯系統這是純虛函數

(3).這是一個聲明語句,最後因該有分号。

(4)如果一個類中有純虛函數,而在其派生類中沒有對該函數的定義,則純虛函數在派生類中仍然為純虛函數。

2.抽象類

含有純虛函數的類被稱為抽象類。

抽象類不能用來定義對象,定義這些類的唯一目的就是用它作為基類去建立派生類。

如果在派生類中對基類的是以純虛函數進行了定義,那麼這些函數就被賦予了功能,可以被調用。這個派生類就不是抽象類,而是可以用來定義對象的具體類,如果而在其派生類中沒有對該函數的定義,則派生類仍然是抽象類,不能用來定義對象。

繼續閱讀