C++是一種支持面向對象編程的高級編程語言。多態性是其面向對象編程的核心特性之一,它允許同一類型的變量在不同的情況下表現出不同的行為。在C++中實現多態性有多種方法,本文將從函數的重載、虛函數、抽象類和接口等方面進行詳細闡述。
一、函數的重載
函數的重載是指在同一作用域內定義多個同名但參數列表不同的函數。函數重載並不涉及到虛函數表的查找和轉移,是一種靜態綁定的方法。下面是一個例子:
// 函數的重載 #include <iostream> using namespace std; class Shape { public: void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; class Rectangle: public Shape { public: int area() { return (width * height); } }; class Triangle: public Shape { public: int area() { return (width * height / 2); } }; int main() { Rectangle Rect; Triangle Tri; Rect.setWidth(5); Rect.setHeight(7); // 調用Rectangle的area函數 cout << "Rectangle area: " << Rect.area() << endl; Tri.setWidth(5); Tri.setHeight(7); // 調用Triangle的area函數 cout << "Triangle area: " << Tri.area() << endl; return 0; }
在本例中,Rectangle和Triangle兩個類都繼承自Shape類,都有setWidth和setHeight函數,並分別定義了自己的area函數來計算面積。通過函數的重載,程序在編譯時就可以靜態地確定應該調用哪個函數,實現多態性。
二、虛函數
虛函數是C++中實現多態性的一種方法。虛函數是在父類中定義的一個函數,它在子類中可以被重寫,這樣當使用子類對象調用該函數時,就可以選擇運行子類重寫的函數而不是父類中定義的函數。虛函數利用虛表實現動態綁定,可以在運行時根據對象類型確定調用的函數。
在C++中,要將一個函數聲明為虛函數,只需要在函數聲明前加上關鍵字virtual,如下所示:
class Base { public: virtual void print() { cout << "Base class print" << endl; } }; class Derived: public Base { public: void print() { // 重寫基類的print函數 cout << "Derived class print" <print(); // 調用由派生類重寫的print函數 return 0; }
在上面的例子中,Base類的print函數被聲明為虛函數,在Derived類中被重寫。在main函數中,通過基類指針bptr訪問派生類對象的print函數時,程序會動態綁定並調用Derived類中的print函數。
三、抽象類
抽象類是一種特殊的類,它不能直接被實例化,而是用作派生其他類的基類。抽象類最重要的特性是其中包含至少一個純虛函數。純虛函數沒有實現,它是一個特殊的虛函數,用來定義接口,並要求派生類必須實現該函數。在C++中,純虛函數的聲明形式如下:
virtual int foo() = 0;
抽象類的存在可以使派生類具有某種共性的特徵,同時也不會影響到派生類的獨特性。下面是一個使用抽象類實現多態的例子:
class Shape { public: virtual int getArea() = 0; // 純虛函數 }; class Rectangle: public Shape { public: Rectangle(int w, int h) { width = w; height = h; } int getArea() { return (width * height); } private: int width; int height; }; class Triangle: public Shape { public: Triangle(int w, int h) { width = w; height = h; } int getArea() { return (width * height / 2); } private: int width; int height; }; int main() { Rectangle Rect(5, 7); Triangle Tri(5, 7); Shape* shape1 = &Rect; // 基類指針指向派生類對象 Shape* shape2 = &Tri; // 基類指針指向派生類對象 cout << "Rectangle area: " <getArea() << endl; cout << "Triangle area: " <getArea() << endl; return 0; }
在上面的例子中,Shape類是抽象類,它包含了一個純虛函數getArea。Rectangle和Triangle兩個類都繼承自Shape類,並實現了自己的getArea函數。程序中,定義了shape1和shape2兩個Shape類型的指針,用於指向Rectangle和Triangle對象,實現多態性。
四、接口
接口是一個純虛類,其中只包含純虛函數,用來定義一個類的行為規範。接口可以讓其他類繼承並實現其中的純虛函數,從而擁有相同的行為規範。在C++中,可以通過抽象類來實現接口的功能。
下面是一個使用抽象類實現接口的例子:
class IShape { public: virtual int getArea() = 0; virtual int getPerimeter() = 0; }; class Rectangle: public IShape { public: Rectangle(int w, int h) { width = w; height = h; } int getArea() { return (width * height); } int getPerimeter() { return (2 * (width + height)); } private: int width; int height; }; class Triangle: public IShape { public: Triangle(int w, int h) { width = w; height = h; } int getArea() { return (width * height / 2); } int getPerimeter() { return (width + height + sqrt(width * width + height * height)); } private: int width; int height; }; int main() { Rectangle Rect(5, 7); Triangle Tri(5, 7); IShape* shape1 = &Rect; IShape* shape2 = &Tri; cout << "Rectangle area: " <getArea() << ", perimeter: " <getPerimeter() << endl; cout << "Triangle area: " <getArea() << ", perimeter: " <getPerimeter() << endl; return 0; }
在本例中,定義了一個IShape接口,包含了getArea和getPerimeter兩個純虛函數。Rectangle和Triangle兩個類都繼承自IShape接口,並實現了它的純虛函數。程序中,定義了shape1和shape2兩個IShape類型的指針,用於指向Rectangle和Triangle對象,實現多態性,同時遵循了IShape接口的行為規範。
原創文章,作者:KCQHF,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/315620.html