日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 面向对象(四)—— 多态 (Polymorphism)

發布時間:2023/12/9 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 面向对象(四)—— 多态 (Polymorphism) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基類的指針(Pointers to base class)

繼承的好處之一是一個指向子類(derived class)的指針與一個指向基類(base class)的指針是type-compatible的。?本節就是重點介紹如何利用C++的這一重要特性。例如,我們將結合C++的這個功能,重寫前面小節中關于長方形rectangle 和三角形 triangle 的程序:

// pointers to base class #include <iostream.h> class CPolygon { protected:int width, height; public:void set_values (int a, int b) {width=a; height=b;} }; class CRectangle: public CPolygon { public:int area (void) {return (width * height);} }; class CTriangle: public CPolygon { public:int area (void) {return (width * height / 2);} }; int main () {CRectangle rect;CTriangle trgl;CPolygon * ppoly1 = &rect;CPolygon * ppoly2 = &trgl;ppoly1->set_values (4,5);ppoly2->set_values (4,5);cout << rect.area() << endl;cout << trgl.area() << endl;return 0; } 20
10

在主函數 main 中定義了兩個指向class CPolygon的對象的指針,即 *ppoly1 和 *ppoly2。 它們被賦值為rect 和 trgl的地址,因為rect 和 trgl是CPolygon 的子類的對象,因此這種賦值是有效的。

使用*ppoly1 和 *ppoly2 取代rect 和trgl 的唯一限制是*ppoly1 和 *ppoly2 是CPolygon* 類型的,因此我們只能夠引用CRectangle 和 CTriangle 從基類CPolygon中繼承的成員。正是由于這個原因,我們不能夠使用*ppoly1 和 *ppoly2 來調用成員函數 area(),而只能使用rect 和 trgl來調用這個函數。

要想使CPolygon 的指針承認area()為合法成員函數,必須在基類中聲明它,而不能只在子類進行聲明(見下一小節)。

?

虛擬成員(Virtual members)

如果想在基類中定義一個成員留待子類中進行細化,我們必須在它前面加關鍵字virtual ,以便可以使用指針對指向相應的對象進行操作。

請看一下例子:

// virtual members #include <iostream.h> class CPolygon {protected:int width, height;public:void set_values (int a, int b) {width=a;height=b;}virtual int area (void) { return (0); } }; class CRectangle: public CPolygon {public:int area (void) { return (width * height); } }; class CTriangle: public CPolygon {public:int area (void) {return (width * height / 2);} }; int main () {CRectangle rect;CTriangle trgl;CPolygon poly;CPolygon * ppoly1 = &rect;CPolygon * ppoly2 = &trgl;CPolygon * ppoly3 = &poly;ppoly1->set_values (4,5);ppoly2->set_values (4,5);ppoly3->set_values (4,5);cout << ppoly1->area() << endl;cout << ppoly2->area() << endl;cout << ppoly3->area() << endl;return 0; } 20
10
0

現在這三個類(CPolygon, CRectangle 和 CTriangle) 都有同樣的成員:width, height, set_values() 和 area()。

area() 被定義為virtual 是因為它后來在子類中被細化了。你可以做一個試驗,如果在代碼種去掉這個關鍵字(virtual),然后再執行這個程序,三個多邊形的面積計算結果都將是 0 而不是20,10,0。這是因為沒有了關鍵字virtual ,程序執行不再根據實際對象的不用而調用相應area() 函數(即分別為CRectangle::area(), CTriangle::area() 和 CPolygon::area()),取而代之,程序將全部調用CPolygon::area(),因為這些調用是通過CPolygon類型的指針進行的。

因此,關鍵字virtual 的作用就是在當使用基類的指針的時候,使子類中與基類同名的成員在適當的時候被調用,如前面例子中所示。

注意,雖然本身被定義為虛擬類型,我們還是可以聲明一個CPolygon 類型的對象并調用它的area() 函數,它將返回0 ,如前面例子結果所示。

?

抽象基類(Abstract base classes)

基本的抽象類與我們前面例子中的類CPolygon 非常相似,唯一的區別是在我們前面的例子中,我們已經為類CPolygon的對象(例如對象poly)定義了一個有效地area()函數,而在一個抽象類(abstract base class)中,我們可以對它不定義,而簡單得在函數聲明后面寫 =0 (等于0)。

類CPolygon 可以寫成這樣:

// abstract class CPolygon class CPolygon {protected:int width, height;public:void set_values (int a, int b) {width=a;height=b;}virtual int area (void) =0; };

注意我們是如何在virtual int area (void)加 =0 來代替函數的具體實現的。這種函數被稱為純虛擬函數(pure virtual function),而所有包含純虛擬函數的類被稱為抽象基類(abstract base classes)。

抽象基類的最大不同是它不能夠有實例(對象),但我們可以定義指向它的指針。因此,像這樣的聲明:

CPolygon poly;

對于前面定義的抽象基類是不合法的。

然而,指針:

CPolygon * ppoly1;
CPolygon * ppoly2

是完全合法的。這是因為該類包含的純虛擬函數(pure virtual function) 是沒有被實現的,而又不可能生成一個不包含它的所有成員定義的對象。然而,因為這個函數在其子類中被完整的定義了,所以生成一個指向其子類的對象的指針是完全合法的。

下面是完整的例子:

// virtual members #include <iostream.h> class CPolygon {protected:int width, height;public:void set_values (int a, int b) {width=a;height=b;}virtual int area (void) =0; }; class CRectangle: public CPolygon {public:int area (void) { return (width * height); } }; class CTriangle: public CPolygon {public:int area (void) {return (width * height / 2);} }; int main () {CRectangle rect;CTriangle trgl;CPolygon * ppoly1 = &rect;CPolygon * ppoly2 = &trgl;ppoly1->set_values (4,5);ppoly2->set_values (4,5);cout << ppoly1->area() << endl;cout << ppoly2->area() << endl;return 0; } 20
10

再看一遍這段程序,你會發現我們可以用同一種類型的指針(CPolygon*)指向不同類的對象,至一點非常有用。 想象一下,現在我們可以寫一個CPolygon 的成員函數,使得它可以將函數area()的結果打印到屏幕上,而不必考慮具體是為哪一個子類。

// virtual members #include <iostream.h> class CPolygon {protected:int width, height;public:void set_values (int a, int b) {width=a;height=b;}virtual int area (void) =0;void printarea (void) {cout << this->area() << endl;} }; class CRectangle: public CPolygon {public:int area (void) { return (width * height); } }; class CTriangle: public CPolygon {public:int area (void) {return (width * height / 2);} }; int main () {CRectangle rect;CTriangle trgl;CPolygon * ppoly1 = &rect;CPolygon * ppoly2 = &trgl;ppoly1->set_values (4,5);ppoly2->set_values (4,5);ppoly1->printarea();ppoly2->printarea();return 0; } 20
10

記住,this 代表代碼正在被執行的這一個對象的指針。

抽象類和虛擬成員賦予了C++ 多態(polymorphic)的特征,使得面向對象的編程object-oriented programming成為一個有用的工具。這里只是展示了這些功能最簡單的用途。想象一下如果在對象數組或動態分配的對象上使用這些功能,將會節省多少麻煩

總結

以上是生活随笔為你收集整理的C++ 面向对象(四)—— 多态 (Polymorphism)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。