多態(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;
}
多態是面向對象編程的一個重要特性,它提供了一種方式,使得相同的接口可以表現出不同的行為,這使得代碼更加靈活和可擴展。
浙公網安備 33010602011771號