多態按字面的意思就是多種形態。當類之間存在層次結構,而且類之間是經過繼承關聯時,就會用到多態。ios
C++ 多態意味着調用成員函數時,會根據調用函數的對象的類型來執行不一樣的函數。函數
小編推薦一個學C語言/C++的學習裙【 712,284,705】,不管你是小白仍是進階者,是想轉行仍是想入行均可以來了解一塊兒進步一塊兒學習!裙內有開發工具,不少乾貨和技術資料分享!工具
下面的實例中,基類 Shape 被派生爲兩個類,以下所示:學習
#include <iostream>開發工具
using namespace std;spa
class Shape {指針
protected:code
int width, height;orm
public:對象
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
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;
}
當上面的代碼被編譯和執行時,它會產生下列結果:
Parent 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;
}
};
修改後,當編譯和執行前面的實例代碼時,它會產生如下結果:
Rectangle 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++的學習環境,能夠加入咱們的C/C++技術交流羣,點擊我加入吧~會節約不少時間,可以在專業牛人大牛的幫助下,攻克不少在學習中遇到的難題。