標籤:就是 綁定 面積 一個 cte 使用 func stream str
多態
多態按字面的意思就是多種形態。當類之間存在階層,並且類之間是通過繼承關聯時,就會用到多態。
C++ 多態意味著調用成員函數時,會根據調用函數的對象的類型來執行不同的函數。
下面的執行個體中,基類 Shape 被派生為兩個類,如下所示:
#include <iostream> using namespace std; class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } virtual int area() { cout << "Parent class area :" <<endl; return 0; }};class Rectangle: public Shape{ public: Rectangle( int a=0, int b=0):Shape(a, b) { } int area () { cout << "Rectangle class area :" <<endl; return (width * height); }};class Triangle: public Shape{ public: Triangle( int a=0, int b=0):Shape(a, b) { } int area () { cout << "Triangle class area :" <<endl; return (width * height / 2); }};// 程式的主函數int main( ){ Shape *shape; Rectangle rec(10,7); Triangle tri(10,5); // 儲存矩形的地址 shape = &rec; // 調用矩形的求面積函數 area shape->area(); // 儲存三角形的地址 shape = &tri; // 調用三角形的求面積函數 area shape->area(); return 0;}
編譯輸出:
[email protected]virtual-machine:~/Documents/Test/C++/eight$ ./1Parent class area :Parent class area :
導致錯誤輸出的原因是,調用函數 area() 被編譯器設定為基類中的版本,這就是所謂的靜態多態,或靜態連結 - 函數調用在程式執行前就準備好了。有時候這也被稱為早綁定,因為 area() 函數在程式編譯期間就已經設定好了。
但現在,讓我們對程式稍作修改,在 Shape 類中,area() 的聲明前放置關鍵字 virtual,如下所示:
class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } virtual int area() { cout << "Parent class area :" <<endl; return 0; }};
修改後,編譯輸出:
[email protected]virtual-machine:~/Documents/Test/C++/eight$ ./1Rectangle class area :Triangle class area :
此時,編譯器看的是指標的內容,而不是它的類型。因此,由於 tri 和 rec 類的對象的地址儲存在 *shape 中,所以會調用各自的 area() 函數。
正如您所看到的,每個子類都有一個函數 area() 的獨立實現。這就是多態的一般使用方式。有了多態,您可以有多個不同的類,都帶有同一個名稱但具有不同實現的函數,函數的參數甚至可以是相同的。
虛函數
虛函數 是在基類中使用關鍵字 virtual 聲明的函數。在衍生類別中重新定義基類中定義的虛函數時,會告訴編譯器不要靜態連結到該函數。
我們想要的是在程式中任意點可以根據所調用的物件類型來選擇調用的函數,這種操作被稱為動態連結,或後期綁定。
純虛函數
您可能想要在基類中定義虛函數,以便在衍生類別中重新定義該函數更好地適用於對象,但是您在基類中又不能對虛函數給出有意義的實現,這個時候就會用到純虛函數。
我們可以把基類中的虛函數 area() 改寫如下:
class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } // pure virtual function virtual int area() = 0;};
= 0 告訴編譯器,函數沒有主體,上面的虛函數是純虛函數。
C++解析八-多態