C++ 靜多態與動多態


多態是指通過單一的標識支持不同的特定行為的能力。

C++中有兩種多態,稱為動多態(運行期多態)靜多態(編譯期多態),而靜多態主要通過模板來實現,宏也是實現靜多態的一種途徑

動多態在C++中是通過虛函數實現的,即在基類中存在一些接口(一般為純虛函數),子類必須重載這些接口。這樣通過使用基類的指針或者引用指向子類的對象,就可以實現調用子類對應的函數的功能。動多態的函數調用機制是執行期才能進行確定,所以它是動態的。

#include <iostream> 
using namespace std;

class shape 
{ 
public: 
    virtual void draw() = 0; 
};

class line : public shape 
{ 
public: 
    void draw() 
    { 
        cout << "line is drawing!" << endl; 
    } 
};

class circle : public shape 
{ 
public: 
    void draw() 
    { 
        cout << "circle is drawing!" << endl; 
    } 
};

int main() 
{ 
    shape* pLine = new line; 
    shape* pCircle = new circle;

//     line line; 
//     circle circl; 
//     
//     shape& referenceLine = line;    //引用 
//     shape& referenceCircl = circl; 
// 
//     referenceLine.draw(); 
//     referenceCircl.draw();

    pLine->draw(); 
    pCircle->draw(); 
    if( pCircle ) delete pCircle ; 
    if( pLine ) delete pLine ; 
    return 0; 
}

靜多態是采用模板機制實現的,沒用基類,因此也不用進行綁定。它不采用虛函數機制,所以所有調用在編譯期就可確定,因此它是靜態的。

#include <iostream> 
using namespace std;

class line 
{ 
public: 
    void draw() 
    { 
        cout << "line is drawing!" << endl; 
    } 
};

class circle 
{ 
public: 
    void draw() 
    { 
        cout << "circle is drawing!" << endl; 
    } 
};

template<typename T> 
void drawShape(T & shape) 
{ 
    shape.draw(); 
}

int main() 
{ 
    line lining; 
    circle circling; 
    drawShape( lining ); 
    drawShape( circling );

    return 0; 
}

動多態的實現要通過虛函數,會產生虛表和虛指針,占用較多的空間,動多態需要在運行期進行綁定,所花費的時間較靜多態多。

  優點:能處理異類集合(容器中存儲基類指針即可)、可執行代碼比較小(只需一個多態函數)、可以完全編譯而不需要發布源碼。
  缺點:不能提前檢查類型的安全性(如向容器中插入錯誤類型的對象)、性能低(有層層繼承)、耦合性高(繼承的耦合性高於組合)。

靜多態在空間和時間上都比動多態表現的好,因此在其他的條件相同的情況下,應該更多的使用靜多態。但是靜多態也有一些缺點,如它不能夠處理異類的集合,也沒有動多態靈活。並且現在大部分編譯器不支持模板的分離編譯,因此要將聲明和實現寫在一個文件中,這樣會暴露更多的細節。

優點:具體類可以只實現需要的接口、生成代碼性能高(無需通過指針的間接調用,非虛函數具有更多的內聯機會)、有更好的類型安全性(類型在編譯期就進行檢查)、耦合性低(各個類相互獨立)、集合的元素類型不再局限於指針。
缺點:不能處理異類集合、可執行代碼比較大(代碼膨脹)、模板庫源碼需要發布、對模板實參類型有約束(比如需要該類型實現了operator<)。

到底用動多態還是靜多態,應該根據情況綜合考慮決定。我們也可以結合動多態和靜多態來獲得一個很好的效率和靈活性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM