多態性
多態性是物件導向程式設計的重要特性之一,字面上可以簡單理解就是:多種形態,多個樣子。其實本質意思也是這樣,在物件導向程式設計中,指同樣的方法被不同物件執行時會有不同的執行效果。
具體來說,多態的實作又可以分為兩種:編譯時多型和執行時多型。前者是編譯的時候就確定了具體的操作過程,後者是在程式運行過程中才確定的操作過程。這種確定操作過程的就是聯編,也稱為綁定。
聯編在編譯連接時確認的,叫做靜態聯編,前面我們學習的函式重載、函式模板的實例化就屬於這一類。另一種是在運作的時候,才能確認執行哪段程式碼的,叫做動態聯編,這種情況是編譯的時候,還無法確認具體走哪段程式碼,而是程式運作起來之後才能確認。
兩者相較之下,靜態聯編由於編譯時候就已經確定好怎麼執行,因此執行起來效率高;而動態聯編想必雖然慢一些,但優點是靈活。兩者各有千秋,有各自不同的使用場景。
下面,我們圍繞著靜態聯編,給大家一個簡單例子:
/**************************************//Des:C++教學demo//Author: Huang//Copyright:www.dotcpp.com//Date:2017/12/20******************************* *******/#include<iostream>usingnamespacestd;#definePI3.1415926classPoint{private:intx,y;public:Point(intx=0,inty=0){this->x=x;this->y =y;}doublearea(){return0.0;}};classCircle:publicPoint{private:intr;public:Circle(intx,inty,intR):Point(x,y){r=R;}doublearea(){ returnPI*r*r;}};intmain(){PointA(10,10);cout<<A.area()<<endl;CircleB(10,10,20);cout<<B.area()< <endl;Point*p;p=&B;cout<<p->area()<<endl;Point&pp=B;cout<<pp.area()<<endl;return0;}
定義了兩個類,一個圓點類,一個衍生出來的圓類,可以看到主函數的程式碼,四個輸出面積的結果,結果如下:
大家可以對照程式碼理解四個輸出:
第一個cout輸出A的面積,是Point類別中的area方法,面積為0,沒有問題。
第二個cout輸出B的面積,很明顯是衍生類別Circle的area方法,面積自然是依公式計算1256.64的值,也沒問題。
第三個cout輸出的是Point類型指標p指向的Circle類別物件的area方法,它輸出了0很明顯是執行了Point類別裡的area方法。這裡C++實行的是靜態聯編,也就是在編譯的時候就依據p的型別來定執行哪個area,因此是0。
第四種cout也同理,把Circle型別的物件賦給Point型別的引用,C++同樣實行靜態聯編,也輸出0。
很明顯,這不是我們更期望的結果,實際上,對於指標、引用,我們更希望執行實際物件的方法,而不是因為這個指標、引用的類型而盲目的確定,這就是如果這麼寫存在的問題。
如果想要達到我們的要求,即無論指標和引用為何類型,都以實際所指向的物件為依據靈活決定。那麼就要更改這種預設的靜態聯編的方法,採用動態聯編,即在運行的時候靈活決定。
下一節,虛函數為大家詳細解釋!