C++整理16_多型

hwaityd發表於2024-10-20

多型(Polymorphism)

1. 什麼是多型

概念:多型是指在不同的上下文中,相同的操作或函式呼叫可能會產生不同的行為。它允許開發者編寫出更通用、更靈活的程式碼。
原理:多型主要透過虛擬函式和函式過載實現。它使得函式呼叫可以根據呼叫物件的實際型別來決定執行哪個函式。
用法:基類中宣告虛擬函式,派生類重寫這些虛擬函式。

案例程式碼

class Animal {
public:
    virtual void speak() {
        cout << "Animal speaks" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() override {
        cout << "Dog barks" << endl;
    }
};

class Cat : public Animal {
public:
    void speak() override {
        cout << "Cat meows" << endl;
    }
};

void makeSound(Animal& animal) {
    animal.speak(); // 多型呼叫
}

int main() {
    Dog dog;
    Cat cat;
    makeSound(dog); // 輸出 Dog barks
    makeSound(cat); // 輸出 Cat meows
    return 0;
}

2. 多型分類

編譯時多型

  • 強制多型(也稱為靜態多型):透過函式過載和運算子過載實現,編譯器在編譯時確定呼叫哪個函式。
  • 過載多型:透過函式過載實現,編譯器根據函式簽名(函式名和引數列表)來決定呼叫哪個函式。
  • 引數化多型:透過模板實現,允許在編譯時根據模板引數生成不同的函式或類例項。

執行時多型

  • 包含多型(也稱為動態多型):透過虛擬函式實現,執行時根據物件的實際型別來決定呼叫哪個函式。

3. 編譯時多型:早繫結

概念:編譯時多型也稱為早繫結,因為函式呼叫的繫結在編譯時就已經確定。
原理:編譯器根據函式簽名或過載決議來決定呼叫哪個函式。
用法:函式過載、運算子過載和模板。

案例程式碼(函式過載):

void print(int i) {
    cout << "Printing int: " << i << endl;
}

void print(double f) {
    cout << "Printing double: " << f << endl;
}

int main() {
    print(5);     // 編譯時確定呼叫 print(int)
    print(5.0);   // 編譯時確定呼叫 print(double)
    return 0;
}

4. 執行時多型:晚繫結

概念:執行時多型也稱為晚繫結,因為函式呼叫的繫結在執行時才確定。
原理:透過虛擬函式表(vtable)和虛擬函式指標(vptr)實現。每個包含虛擬函式的類都有一個虛擬函式表,物件會包含一個指向該表的指標。
用法:在基類中宣告虛擬函式,在派生類中重寫這些虛擬函式。

案例程式碼(虛擬函式):

class Base {
public:
    virtual void func() {
        cout << "Base::func()" << endl;
    }
};

class Derived : public Base {
public:
    void func() override {
        cout << "Derived::func()" << endl;
    }
};

int main() {
    Base* b = new Derived();
    b->func(); // 執行時確定呼叫 Derived::func()
    delete b;
    return 0;
}

多型是物件導向程式設計的一個重要特性,它提供了一種方式,使得相同的介面可以表現出不同的行為,這使得程式碼更加靈活和可擴充套件。

相關文章