Item 41: 瞭解隱式接口和編譯期多態

通常顯式接口由函數的簽名式(函數名稱、參數類型、返回類型)構成。例如

Widget classclass Widget{
  public:
    Widget();
    virtual ~Widget();
    virtual std::size_t size() const;
    virtual void normalize();
    void swap( Widget& other );
};

其public接口由一個構造函數、析構函數、函數size、normalize、swap及其參數類型、返回類型、常量性構成。
隱式接口就完全不一樣了。它並不基於函數簽名式,而是由有效表達式組成。例如下面的模板函數doProcessing:

template<typename T>
void doProcessing( T& w ){
  if( w.size() > 10 && w != someNastyWidget )
    ...
}

T的隱式接口看起來好像有這些約束:
(1)它必須提供一個名爲size的成員函數,該函數返回一個整數值。
(2)它必須支持一個operator!=函數,用來比較兩個T對象,
但其實這兩個約束都不需要滿足。T必須支持size函數,但是這個函數也可能從base class繼承而得;這個成員函數不一定需要返回一個整數值,甚至不需要返回一個數值類型。它唯一需要做的是返回一個類型爲X的對象,該對象加上一個int型後可以調用一個operator>。同樣道理,T也不需要支持operator!=,只要存在一個operator!=,它接受一個類型爲X的對象和一個類型爲Y的對象,T可被轉換爲X而someNastyWidget可被轉換爲Y。
總結起來,
對class而言,接口是顯式的,以函數簽名爲中心。多態則是通過virtual函數發生於運行期。
對template參數而言,接口是隱式的,基於有效表達式。多態則是通過template具現化和函數重載解析,發生於編譯期。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章