C++中的多型性
你好,有抱負的程式設計師!今天,我們將踏上一段令人興奮的旅程,進入C++多型性的世界。如果這個詞對你來說很嚇人,別擔心——在上完這堂課後,你將會對多型性像對待你最喜歡的運動鞋一樣感到舒適!
什麼是多型性?
在我們深入代碼之前,讓我們先了解多型性實際上意味著什麼。這個詞來自希臘語:「poly」意為多個,「morph」意為形態。在程式設計中,多型性允許不同類型的物件被當作公共基礎類型的物件對待。這就像擁有一個通用遙控器,可以控制各種設備——非常酷,對吧?
實際世界中的類比
想象一下你在一個動物園。你看到不同的動物——獅子、大象、企鵝。它們都是動物,但它們的行為不同。當到了餵食時間,動物園的管理員不需要知道每一隻動物的具體類型。他們只需要發出一個一般的「吃」命令,每隻動物就會以自己的方式做出反應。這就是多型性的實踐!
虛擬函數
現在,讓我們深入了解C++多型性的細節,從虛擬函數開始。
什麼是虛擬函數?
虛擬函數是C++中的特殊函數,它允許程式在運行時根據所引用的物件類型來決定要調用哪個函數,而不是根據指針或引用的類型。
以下是一個簡單的例子:
#include <iostream>
using namespace std;
class Animal {
public:
virtual void makeSound() {
cout << "The animal makes a sound" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
cout << "The dog barks: Woof!" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
cout << "The cat meows: Meow!" << endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->makeSound(); // 輸出:The dog barks: Woof!
animal2->makeSound(); // 輸出:The cat meows: Meow!
delete animal1;
delete animal2;
return 0;
}
讓我們來解析一下:
- 我們有一個基礎類
Animal
,其中有一個虛擬函數makeSound()
。 - 我們創建了兩個派生類
Dog
和Cat
,它們各自重寫了makeSound()
函數。 - 在
main()
中,我們創建了類型為Animal*
的指針,但將它們分配給了Dog
和Cat
的物件。 - 當我們調用
makeSound()
時,程式會根據實際的物件類型調用正確的版本,而不是指針類型。
這就是虛擬函數和多型性的魔力!
虛擬關鍵字
virtual
關鍵字在這裡至關重要。它告訴編譯器這個函數可能在派生類中被重寫。如果没有它,程式將始終調用基礎類型的函數版本。
純虛擬函數
現在,讓我們升級並談談純虛擬函數。
什麼是純虛擬函數?
純虛擬函數是在基礎類中沒有實現的虛擬函數。它通過將0分配給函數聲明來聲明。
以下是一個例子:
#include <iostream>
using namespace std;
class Shape {
public:
virtual double area() = 0; // 純虛擬函數
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() override {
return 3.14159 * radius * radius;
}
};
class Rectangle : public Shape {
private:
double length, width;
public:
Rectangle(double l, double w) : length(l), width(w) {}
double area() override {
return length * width;
}
};
int main() {
Shape* shape1 = new Circle(5);
Shape* shape2 = new Rectangle(4, 5);
cout << "Circle area: " << shape1->area() << endl;
cout << "Rectangle area: " << shape2->area() << endl;
delete shape1;
delete shape2;
return 0;
}
在這個例子中:
-
Shape
是一個抽象基礎類,其中有一個純虛擬函數area()
。 -
Circle
和Rectangle
是具體的類,它們繼承自Shape
並提供了自己的area()
實現。 - 我們可以創建
Shape
指針,並將它們分配給Circle
和Rectangle
的物件。 - 當我們調用
area()
時,會根據實際的物件類型調用正確的版本。
抽象類
至少具有一個純虛擬函數的類稱為抽象類。你不能創建抽象類的物件,但你可以使用指針和引用來指涉抽象類型。
為什麼使用多型性?
- 靈活性:它允許你撰寫可以與多種類型的物件一起工作的代碼。
- 可擴展性:你可以添加新的派生類,而不需要更改現有的代碼。
- 簡單性:它可以通过允許你統一對待不同的物件來簡化代碼。
多型性中的常見方法
以下是C++多型性中常見的方法的表格:
方法 | 描述 |
---|---|
virtual |
在基礎類中聲明虛擬函數時使用的關鍵字 |
override |
在派生類中用來表示函數重寫了基礎類函數的關鍵字 |
= 0 |
用來聲明純虛擬函數 |
dynamic_cast |
在多型性類階層中用於安全的向下轉型 |
typeid |
用於在運行時獲取類型信息 |
結論
多型性是C++中一個強大的功能,它允許靈活和可擴展的代碼。通過使用虛擬函數和純虛擬函數,你可以創建可以交替使用的類階層,從而產生更模塊化和可維護的代碼。
記住,就像學習任何新技能一樣,掌握多型性需要練習。如果一開始沒有立即領悟,別氣餒——繼續編程,繼續實驗,很快你就會像專業一樣進行多型性變換!
Credits: Image by storyset