一、动态多态
- 动态多态通过虚函数和继承关系来实现,执行动态绑定,在通过基类的指针或者引用调用虚函数运行时确定。
#include <iostream>
#include <cmath>
class Shape {
public:
virtual double computeArea() const = 0; // 纯虚函数
virtual ~Shape() = default; // 虚析构函数
};
class Circle : public Shape {
public:
Circle(double radius) : radius(radius) {}
double computeArea() const override {
double area = M_PI * radius * radius;
return area;
}
private:
double radius;
};
class Rectangle : public Shape {
public:
Rectangle(double width, double height) : width(width), height(height) {}
double computeArea() const override {
double area = width * height;
return area;
}
private:
double width, height;
};
int main() {
Shape* circle = new Circle(5.0);
// 输出:Circle area: 78.5398
std::cout << "Circle area: " << circle->computeArea() << std::endl;
Shape* rectangle = new Rectangle(4.0, 6.0);
// 输出:Rectangle area: 24
std::cout << "Rectangle area: " << rectangle->computeArea() << std::endl;
delete circle;
delete rectangle;
return 0;
}
二、CRTP静态多态
1、CRTP多态简介
- CRTP(Curiously Recurring Template Pattern,奇异递归模板模式)是C++的一种设计模式,特点是利用模板和继承,在基类关联派生类模板参数,来实现静态多态性,不需要使用虚函数实现多态特性。
2、定义基类
- 定义一个模板基类Shape,接收一个派生类作为模板参数。
#include <iostream>
#include <cmath>
template <typename Derived>
class Shape {
public:
double area() {
return static_cast<Derived*>(this)->computeArea();
}
};
- Shape基类中,area方法内部调用了派生类的computeArea方法,用static_cast可以确保在编译时进行类型检查。
3、定义派生类
class Circle : public Shape<Circle> {
public:
Circle(double radius) : radius(radius) {}
double computeArea() {
double area = M_PI * radius * radius;
return area;
}
private:
double radius;
};
class Rectangle : public Shape<Rectangle> {
public:
Rectangle(double width, double height) : width(width), height(height) {}
double computeArea() {
double area = width * height;
return area;
}
private:
double width, height;
};
4、CRTP使用
int main() {
Circle circle(5.0);
// 输出:Circle area: 78.5398
std::cout << "Circle area: " << circle.area() << std::endl;
Rectangle rectangle(4.0, 6.0);
// 输出:Rectangle area: 24
std::cout << "Rectangle area: " << rectangle.area() << std::endl;
return 0;
}
多态特性 | 虚函数 | CRTP |
---|
多态性 | 运行时多态 | 静态多态 |
性能开销 | 虚函数表开销 | 无虚函数表开销 |
类型安全 | 运行时检查 | 编译时检查 |
代码维护 | 容易 | 可能更复杂,编译时间较长 |
使用场景 | 需要灵活性(比如定义域实现分离)和动态性 | 性能敏感和静态多态的场景 |