C++中類(lèi)的分層設計(純虛函數)
首先說(shuō)明一下我只是一個(gè)初學(xué)者,寫(xiě)出來(lái)的東西可能會(huì )有錯誤,說(shuō)實(shí)在的沒(méi)寫(xiě)過(guò)多少代碼,但是我認為寫(xiě)代碼是一個(gè)熟練的過(guò)程,一個(gè)完成思想的過(guò)程。只有有了思想,才能完成好的設計,不斷的思考,不斷的總結才能學(xué)到新學(xué)到的東西,才能達到更高的目標。
在C++中虛函數是指將一個(gè)類(lèi)中的虛函數后面加上=0,就說(shuō)明該虛函數為純虛函數。一般該函數設置為純虛函數,那么該函數也就沒(méi)有再次定義的必要了,因為存在純虛函數的類(lèi)就是一個(gè)抽象類(lèi),是不能夠創(chuàng )建對象的,不能創(chuàng )建對象也就不會(huì )主動(dòng)的調用該函數,哪怕在動(dòng)態(tài)綁定的情況下也不會(huì ),因此不需要為該函數定義相關(guān)的操作,實(shí)質(zhì)上在此處聲明只是說(shuō)明在該派生類(lèi)中需要重寫(xiě)基類(lèi)的虛函數,至于是否真的復寫(xiě),不要去關(guān)心。
//存在純虛函數的類(lèi)為抽象類(lèi)
class AbstructClass:public Base
{
public:
//構造函數
AbstructClass(...):Base(...),...{}
//析構函數
~AbstructClass(){...}
//這就是純虛函數,一般func在基類(lèi)中就為虛函數,因此virtual也可以不寫(xiě)
virtual func(...) const = 0;
//保證派生類(lèi)能夠訪(fǎng)問(wèn)數據成員,必須設置為protected
protected:
//一些數據成員定義
...
};
抽象類(lèi)的作用主要是幫助完成實(shí)際派生類(lèi)的設計,為什么這么說(shuō)呢?如果我們只創(chuàng )建一個(gè)基類(lèi),直接繼承基類(lèi)創(chuàng )建實(shí)際的派生類(lèi),存在很多的問(wèn)題,為什么這么說(shuō)呢?比如說(shuō)我要創(chuàng )建一個(gè)人的類(lèi),我們每一個(gè)人都是一個(gè)人的對象,在人的基類(lèi)中一般只是包含了人的共性,不可能將某一個(gè)人的特殊定義到類(lèi)中,當然為了繼承,肯定也會(huì )創(chuàng )建一系列的虛函數。如果我們每一個(gè)人都直接從該基類(lèi)派生,人的個(gè)體在世界上有60多億,我們每一個(gè)人實(shí)際上就是一個(gè)派生類(lèi),因為每一個(gè)人都不同,都有自己獨特的特性(假設是一種數據對象),如果要實(shí)現這么多的派生類(lèi)真的是一個(gè)不可想象的,而且我們可以知道很多人(類(lèi))實(shí)際上存在很多的相似性。
這時(shí)我們實(shí)際上就可以采用抽象類(lèi)來(lái)幫忙完成我們的設計。抽象類(lèi)是連接在基類(lèi)和實(shí)際派生類(lèi)之間的中間類(lèi),實(shí)際派生類(lèi)的直接基類(lèi)是抽象類(lèi),也就說(shuō)說(shuō)基類(lèi)是實(shí)際派生類(lèi)的間接基類(lèi)。在抽象層中主要完成什么操作呢?抽象層中主要完成對派生類(lèi)共性數據成員的定義,為了方便派生類(lèi)的數據訪(fǎng)問(wèn),必須設置為受保護訪(fǎng)問(wèn)權限,創(chuàng )建純虛函數,定義構造函數,應該在初始化列表中首先創(chuàng )建基類(lèi)對象,然后才能完成其他成員的初始化,有時(shí)候可能需要復制控制函數的實(shí)現。
在實(shí)際的派生類(lèi)設計過(guò)程中就不再直接從基類(lèi)繼承,而是從抽象類(lèi)中繼承,因為抽象類(lèi)中增加了一些受保護成員數據,且這些數據成員時(shí)派生類(lèi)的共性,因此派生類(lèi)中可以很方便的訪(fǎng)問(wèn)。同時(shí)在該派生類(lèi)中就應該完成虛函數的復寫(xiě)操作,因為動(dòng)態(tài)綁定以后會(huì )直接調用該版本的虛函數。當然有時(shí)候也要完成復制控制函數的定義。當然可以設計很多基于抽象類(lèi)的派生類(lèi)。當然在派生類(lèi)中也可以增加自己的數據成員。
//實(shí)際派生類(lèi)從抽象類(lèi)中繼承
class ActualClass : public AbstructClass
{
public:
ActualClass(...):AbstructClass(...),...{}
//派生類(lèi)中復寫(xiě)虛函數
func()
{...}
private:
//派生類(lèi)的一些數據
...
};
基本的思想如下圖所示:
從上面的圖可知,我們可以在實(shí)際的派生類(lèi)與基類(lèi)之間增加一個(gè)中間層,這種實(shí)現方式不僅能夠更好的隱藏數據,而且比較好的解決了我們上面提到的派生類(lèi)過(guò)實(shí)現過(guò)于復雜的問(wèn)題。因此我們可以認為抽象類(lèi)實(shí)際上就是一個(gè)分層設計的方法,也可以認為是一個(gè)分成更加精細子類(lèi)的方式方法,也就是說(shuō)在基類(lèi)的基礎上將對象分成很多子類(lèi)(抽象類(lèi)),然后在各個(gè)子類(lèi)下設計新的派生類(lèi)。比如在圖中的抽象類(lèi)1,抽象類(lèi)2是不同的,是兩種不同的分類(lèi),這候我們給予兩個(gè)抽象類(lèi)的派生類(lèi)當然也就存在了差別。這樣實(shí)現的好處能夠避免很多的重復代碼。
評論