Effective C++第七章-模板和泛型編程之編譯期多態(運行期多態)和隱式接口(顯式接口)

運行期多態(虛函數)和編譯器多態(模板)

運行期多態的說明示例:

class Animal    //基類
{
public :
    virtual void shout() = 0;
};
class Dog :public Animal
{
public:
    virtual void shout(){ cout << "汪汪!"<<endl; }
};
class Cat :public Animal
{
public:
    virtual void shout(){ cout << "喵喵~"<<endl; }
};

void main()
{
    Animal * anim1 = new Dog;
    Animal * anim2 = new Cat;
   //藉由指針(或引用)調用的接口,在運行期確定指針(或引用)所指對象的真正類型,調用該類型對應的接口--運行期多態
    anim1->shout();
    anim2->shout();
    //delete 對象
    ...
}

編譯期多態的說明示例:

class Animal
{
public :
    void shout() { cout << "發出動物的叫聲" << endl; };
};
class Dog
{
public:
     void shout(){ cout << "汪汪!"<<endl; }
};
class Cat
{
public:
     void shout(){ cout << "喵喵~"<<endl; }
};
template <typename T>
void  animalShout(T & t)
{
    t.shout();//在編譯期間,編譯器推斷出模板參數,因此確定調用的shout是哪個具體類型的接口。--編譯期多態
}
int main()
{
    Animal anim;
    Dog dog;
    Cat cat;
    animalShout(anim);
    animalShout(dog);
    animalShout(cat);
}

顯式接口(class)和隱式接口(template)

組成 什麼時候完成檢查
顯式接口 函數的簽名式(函數名稱,參數類型、返回類型)
隱式接口 有效表達式

顯式接口的說明示例:

class widget{
public:
    widget();
    virtual ~widget();
    virtual std::size_t size() const;
    void swap(widget& other);
};
//其public接口由一個構造函數、一個析構函數、size函數、swap函數及其參數類型、返回類型、常量性構成。也包括編譯器產生的copy函數(copy構造函數和copy assignment操作符)

隱式接口的說明示例:

template<typename T>
void dofun(T& w)
{
    if(w.size() > 10 && w != value){...}
}
//T必須支持size成員函數,然而這個函數也可能從base class繼承。這個成員函數不需返回一個整數值,甚至不需返回一個數值類型。就此而言,甚至不需要返回一個定義有operator>的類型!唯一需要的是返回一個類型爲X的對象,X對象加上int必須能調用一個operator>。
//同樣的道理,T並不需要支持operator!=,因爲operator!=接受一個類型爲X的對象和一個類型爲Y的對象,T可被轉換爲X而value的類型可被轉換爲Y,這樣就可以有效調用operator!=
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章