本節書摘來自異步社群出版社《c++面向對象高效程式設計(第2版)》一書中的第章,第2.10節,作者: 【美】kayshav dattatri,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
c++面向對象高效程式設計(第2版)
下面的示例用于說明,在c中一個簡單棧的實作。
stackid createstack()
{
/* 此處代碼用于建立一個新的stack
傳回新的棧名(stackid) */
}
bool destroystack(stackid whichstack)
/ 此處代碼用于銷毀whichstack /
void push(stackid whichstack, int thiselement)
/ 此處代碼用于将thiselement 壓入whichstack /
int pop(stackid whichstack)
/ 此處代碼用于從whichstack中彈出頂部元素 /
}<code>`</code>
stack.c檔案與stack.h檔案一同編譯後,把産生的目标碼和stack.h檔案一起提供給使用者。stack的使用者不能通路用于操控棧的函數源代碼。
stack的資料結構隻是一段啞資料(dumb data),正确使用stack所需要的資訊都嵌入在push、pop等用于支援資料結構的函數中。對使用者而言,重要的資訊全都在stack的資料結構中,函數隻提供了一個操控資料的工具。但是,使用者不使用提供的函數也可通路和修改stack的資料結構,編譯器無法制止使用者這樣做。換而言之,資料結構和函數之間缺乏緊密耦合。然而,在面向對象程式設計(oop)語言中,函數與資料結構形成一個完整的單元(stack類),必須使用該類提供的函數才能通路對象中的資料。對象擁有資料結構,且隻允許接口通路它。由此可見,在支援oop的語言中更容易實作抽象資料類型。
在面向過程語言中,程式員定義類型與語言定義的新類型非常相似,但前者沒有太多保護,任何人都可以直接修改它們。這樣的程式員定義類型稱為抽象資料類型(abstract data type)。之前我們設計的ld播放機就是一個抽象資料類型。oop語言的優勢在于,它提供資料封裝,保護了實作(是以也保護了實作者)。是以,在oop中,程式員定義類型可被當做語言定義類型。換句話說,oop語言有特權,也有責任。
舉個例子,考慮一個整數資料類型,用于表示非常大的數字(常用于天文學中)。32位整數(4位元組整數)無法滿足我們的要求,是以需要建立一個新類型,即一個抽象資料類型,tint。
抽象資料類型——tint
操作(接口):
加(操作符+)
減(操作符-)
乘(操作符×)
除(操作符/)
求模(操作符%)
增加(操作符+=)
幂
絕對值
列印
…
在該例中,肯定要隐藏tint類型的實作細節。我們可能使用兩個4位元組整數(或一個8位元組的數組)來實作這個新類型,但是tint的客戶并不知道(也不應該知道)這些細節。如果将來使用支援64位整數(這很有可能)的處理器,就可以直接在實作中使用,不用我們目前的這種表示方法,這些都由實作者決定。
利用資料抽象,我們建立了一個新類型,并且為這個新類型提供了一組有用的操作。因為語言沒有直接支援這個類型,是以程式員隻好利用抽象實作它,是以它是一個抽象資料類型。鑒于此,資料抽象有時也被定義為:定義抽象資料類型以及一組操作并隐藏實作的過程。