多态(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;
}
多态是面向对象编程的一个重要特性,它提供了一种方式,使得相同的接口可以表现出不同的行为,这使得代码更加灵活和可扩展。
作者:
hwaityd
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。