静态关联(基于模板的静态多态)
- 原理:
- 静态关联发生在编译期,编译器根据模板参数确定具体调用的函数版本。在模板元编程中,不同的模板实例化会生成不同的代码,这使得编译器能够在编译期就完成函数调用的绑定。
- 在计算几何图形面积库中的运用:
template <typename T>
struct Shape {
virtual T area() const = 0;
};
template <typename T>
struct Circle : public Shape<T> {
T radius;
Circle(T r) : radius(r) {}
T area() const override {
return 3.14159 * radius * radius;
}
};
template <typename T>
struct Rectangle : public Shape<T> {
T width;
T height;
Rectangle(T w, T h) : width(w), height(h) {}
T area() const override {
return width * height;
}
};
template <typename ShapeType>
constexpr auto calculateAreaAtCompileTime(const ShapeType& shape) {
return shape.area();
}
int main() {
Circle<double> circle(5.0);
Rectangle<double> rectangle(4.0, 6.0);
constexpr auto circleArea = calculateAreaAtCompileTime(circle);
constexpr auto rectangleArea = calculateAreaAtCompileTime(rectangle);
return 0;
}
- 这里利用模板在编译期生成不同的计算面积代码,提高了效率,且由于类型在编译期确定,保证了类型安全。
动态关联(基于虚函数的动态多态)
- 原理:
- 动态关联发生在运行时,通过对象的虚函数表指针找到对应的虚函数实现。当使用基类指针或引用调用虚函数时,程序在运行时根据对象的实际类型来确定调用哪个虚函数的实现。
- 在计算几何图形面积库中的运用:
int main() {
std::vector<std::unique_ptr<Shape<double>>> shapes;
shapes.emplace_back(std::make_unique<Circle<double>>(5.0));
shapes.emplace_back(std::make_unique<Rectangle<double>>(4.0, 6.0));
for (const auto& shape : shapes) {
std::cout << "Area: " << shape->area() << std::endl;
}
return 0;
}
int main() {
int choice;
std::cout << "1. Circle\n2. Rectangle\nEnter your choice: ";
std::cin >> choice;
std::unique_ptr<Shape<double>> shape;
if (choice == 1) {
double radius;
std::cout << "Enter radius: ";
std::cin >> radius;
shape = std::make_unique<Circle<double>>(radius);
} else if (choice == 2) {
double width, height;
std::cout << "Enter width and height: ";
std::cin >> width >> height;
shape = std::make_unique<Rectangle<double>>(width, height);
}
if (shape) {
std::cout << "Area: " << shape->area() << std::endl;
}
return 0;
}
- 这样在运行时根据用户输入选择不同的图形类型,并通过虚函数动态调用相应的面积计算函数,实现了灵活性。
结合使用
- 在复杂模板元编程场景下,对于编译期能够确定的部分,使用静态关联来提高效率和类型安全性。例如,在编译期已知图形类型的情况下,通过模板实例化计算面积。
- 对于运行时才确定的部分,如根据用户输入选择图形类型,使用动态关联来实现灵活性。通过基类指针或引用调用虚函数,在运行时确定具体调用的函数实现。这样可以在一个库中同时实现高效的编译期计算和灵活的运行时选择,满足复杂场景的需求。