1. 静态多态
- 实现方式:通过函数重载和模板(函数模板、类模板)来实现。在编译期,编译器根据函数参数的类型、个数或模板参数的不同,确定调用哪个具体的函数版本。
- 示例 - 函数重载:
#include <iostream>
// 函数重载示例
void print(int num) {
std::cout << "Printing integer: " << num << std::endl;
}
void print(double num) {
std::cout << "Printing double: " << num << std::endl;
}
int main() {
print(5);
print(3.14);
return 0;
}
#include <iostream>
// 函数模板示例
template <typename T>
void print(T num) {
std::cout << "Printing value: " << num << std::endl;
}
int main() {
print(10);
print(3.14f);
print("Hello");
return 0;
}
- 应用场景:在编写通用的算法或工具函数时,函数重载可以根据不同的数据类型提供不同的实现,而模板则可以在编译期生成针对不同类型的代码,提高代码复用性。例如标准库中的
std::sort
函数,它可以对不同类型的容器进行排序,通过模板实现了对各种可比较类型的支持。
2. 动态多态
- 实现方式:通过虚函数和指针或引用(基类指针或引用指向派生类对象)来实现。在运行期,程序根据对象的实际类型来决定调用哪个虚函数的实现。这依赖于虚函数表(vtable)和虚指针(vptr)机制。每个包含虚函数的类都有一个虚函数表,类的对象含有一个虚指针,指向该虚函数表。当通过基类指针或引用调用虚函数时,程序会根据虚指针找到虚函数表,进而找到对应对象实际类型的虚函数实现。
- 示例:
#include <iostream>
class Shape {
public:
virtual void draw() {
std::cout << "Drawing a shape" << std::endl;
}
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a circle" << std::endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a rectangle" << std::endl;
}
};
int main() {
Shape* shapes[2];
shapes[0] = new Circle();
shapes[1] = new Rectangle();
for (int i = 0; i < 2; ++i) {
shapes[i]->draw();
}
for (int i = 0; i < 2; ++i) {
delete shapes[i];
}
return 0;
}
- 应用场景:在面向对象编程中,动态多态常用于实现基于继承体系的行为多态。例如在图形绘制系统中,不同的图形类(如圆形、矩形等)继承自一个基类
Shape
,通过动态多态可以根据实际的图形类型调用相应的draw
函数进行绘制。在游戏开发中,不同的角色类(玩家、怪物等)继承自一个基类,通过动态多态可以根据实际的角色类型执行不同的行为,如攻击、移动等。