C++中的多型性

你好,有抱負的程式設計師!今天,我們將踏上一段令人興奮的旅程,進入C++多型性的世界。如果這個詞對你來說很嚇人,別擔心——在上完這堂課後,你將會對多型性像對待你最喜歡的運動鞋一樣感到舒適!

C++ Polymorphism

什麼是多型性?

在我們深入代碼之前,讓我們先了解多型性實際上意味著什麼。這個詞來自希臘語:「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;
}

讓我們來解析一下:

  1. 我們有一個基礎類Animal,其中有一個虛擬函數makeSound()
  2. 我們創建了兩個派生類DogCat,它們各自重寫了makeSound()函數。
  3. main()中,我們創建了類型為Animal*的指針,但將它們分配給了DogCat的物件。
  4. 當我們調用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;
}

在這個例子中:

  1. Shape是一個抽象基礎類,其中有一個純虛擬函數area()
  2. CircleRectangle是具體的類,它們繼承自Shape並提供了自己的area()實現。
  3. 我們可以創建Shape指針,並將它們分配給CircleRectangle的物件。
  4. 當我們調用area()時,會根據實際的物件類型調用正確的版本。

抽象類

至少具有一個純虛擬函數的類稱為抽象類。你不能創建抽象類的物件,但你可以使用指針和引用來指涉抽象類型。

為什麼使用多型性?

  1. 靈活性:它允許你撰寫可以與多種類型的物件一起工作的代碼。
  2. 可擴展性:你可以添加新的派生類,而不需要更改現有的代碼。
  3. 簡單性:它可以通过允許你統一對待不同的物件來簡化代碼。

多型性中的常見方法

以下是C++多型性中常見的方法的表格:

方法 描述
virtual 在基礎類中聲明虛擬函數時使用的關鍵字
override 在派生類中用來表示函數重寫了基礎類函數的關鍵字
= 0 用來聲明純虛擬函數
dynamic_cast 在多型性類階層中用於安全的向下轉型
typeid 用於在運行時獲取類型信息

結論

多型性是C++中一個強大的功能,它允許靈活和可擴展的代碼。通過使用虛擬函數和純虛擬函數,你可以創建可以交替使用的類階層,從而產生更模塊化和可維護的代碼。

記住,就像學習任何新技能一樣,掌握多型性需要練習。如果一開始沒有立即領悟,別氣餒——繼續編程,繼續實驗,很快你就會像專業一樣進行多型性變換!

Credits: Image by storyset