條款41 了解隱式介面和編譯期多型

2021-10-02 09:41:37 字數 1741 閱讀 4599

(1)簡介

物件導向程式設計總是以顯式介面和執行期多型來解決問題。例如:

class

widget

;void

doprocessing

(widget& w)

}

(2)所謂的顯式介面

由於w的型別被宣告為widget,因此w需要widget介面,並且我們可以在原始碼中找到這個介面,看到原始碼的樣子,所以稱為是顯式介面

(3)所謂的執行期多型

由於widget的某些函式是虛函式,因此w的某些函式在執行期間才可以根據w的型別動態呼叫相關版本的函式,這就是所謂的執行期多型

(1)泛型程式設計與物件導向程式設計的不同之處

在泛型程式設計中,顯式介面與執行期多型仍有使用,但是其主要應用的是隱式介面和編譯期多型。

例如將剛才的函式改為函式模板:

template

<

typename t>

void

doprocessing

(t& w)

}

(2)所謂的隱式介面
void

doprocessing

(t& w)

//w需要支援的操作都是隱式介面

這個時候w發生了什麼樣的改變呢?

w所需要支援的介面需要當函式模板具現化時執行於w身上的操作決定(執行了什麼操作,說明w一定需要支援這些介面),例子中w使用了size、normalize、swap函式、copy建構函式、不等比較。並且if語句中還有乙個長表示式。這所有的函式與長表示式便是t必須支援的一組隱式介面(其實就是w需要被約束的東西)。(w.size() > 10 && w != somenastywidget)

(3)所謂的編譯期多型

使用到w的任何函式呼叫,都可能會造成模板具現化,這樣的函式具現化發生在編譯期,而且不同的模板引數導致不同的模板函式,這就是所謂的編譯期多型

通常顯式介面是由函式的簽名式(函式名稱、引數型別、返回型別)構成。

但是隱式介面不是基於簽名式的,而是由有效表示式組成。

例如:

template

<

typename t>

void

doprocess

(t& w)

w.

size()

>

10&&w!=somenastywidget//這就是所謂的隱式介面,是一組有效表示式。

w的隱式介面似乎有下述的約束:

但是實際上由於操作符過載的關係,隱式介面實際上不需要滿足這兩個約束。原因如下:

總之,隱式介面就是一組表示式,不管中間過程怎麼樣,只要最終的結果是乙個滿足類似於上述if語句中的表示式應該有的結果就行,比如if的條件表示式應該是bool型別的,只要括號裡的表示式最終的結果是bool型別即可。表示式中間的介面可能並不需要w去支援。這些就是所謂的隱式介面。

普通的呼叫的函式也是對於w的約束,因此也是乙個隱式介面。長表示式也是隱式介面,但是由於操作符過載的關係,可能w並不需要滿足其中的一些約束。

無論是隱式介面還是顯式子介面,都是在編譯期完成檢查,如果傳遞乙個不支援所謂的隱式介面的模板引數給函式模板,同樣的不能夠通過編譯。

條款41 了解隱式介面以及編譯期多型

相對於繼承體系來說,template實際上也使用介面與多型,而繼承體系往往使用到的是顯式介面以及執行期多型,而template實際上用的是隱式介面以及編譯期多型。隱式介面實際上就是類似下面這樣的東西 1 template 2int mytypes t tmp 3 這裡的size相當於這裡的隱式介面。...

1 了解隱式介面和編譯期多型

顯式介面,執行期多型 物件導向程式設計解決問題的方式 顯式介面 我們知道它是什麼樣子,在原始碼中明確可見。虛函式 提供執行期多型支援,根據動態型別決定呼叫函式。模板和泛型程式設計的重點是隱式介面和編譯期多型 看下面這個模板函式 cpp emplate void dosometing t w temp...

Item 41 隱式介面和編譯時多型

oop程式設計與類屬程式設計 generic programming 的一大區別 1 oop使用顯式的介面和執行時多型 2 類屬程式設計使用隱式介面和編譯時多型 當你看到上面的 時,你能在某個檔案裡找到下面的宣告 widget支援什麼函式一目了然,此之謂 顯式介面 許多函式以virtual打頭,需在...