多態是指經過單一的標識支持不一樣的特定行爲的能力。ios
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; }
動多態的實現要經過虛函數,會產生虛表和虛指針,佔用較多的空間,動多態須要在運行期進行綁定,所花費的時間較靜多態多。spa
優勢:能處理異類集合(容器中存儲基類指針便可)、可執行代碼比較小(只需一個多態函數)、能夠徹底編譯而不須要發佈源碼。
缺點:不能提早檢查類型的安全性(如向容器中插入錯誤類型的對象)、性能低(有層層繼承)、耦合性高(繼承的耦合性高於組合)。指針
靜多態在空間和時間上都比動多態表現的好,所以在其餘的條件相同的狀況下,應該更多的使用靜多態。可是靜多態也有一些缺點,如它不可以處理異類的集合,也沒有動多態靈活。而且如今大部分編譯器不支持模板的分離編譯,所以要將聲明和實現寫在一個文件中,這樣會暴露更多的細節。code
優勢:具體類能夠只實現須要的接口、生成代碼性能高(無需經過指針的間接調用,非虛函數具備更多的內聯機會)、有更好的類型安全性(類型在編譯期就進行檢查)、耦合性低(各個類相互獨立)、集合的元素類型再也不侷限於指針。
缺點:不能處理異類集合、可執行代碼比較大(代碼膨脹)、模板庫源碼須要發佈、對模板實參類型有約束(好比須要該類型實現了operator<)。對象
到底用動多態仍是靜多態,應該根據狀況綜合考慮決定。咱們也能夠結合動多態和靜多態來得到一個很好的效率和靈活性。blog