C++ 高级设计模式:从理论到复杂实现
\n\n设计模式是软件开发中常见问题的经过验证的解决方案。如果基础模式(Singleton、Factory、Observer)每位开发者都熟悉,那么高级技术则需要深入理解 C++ 语言、其模板、多重继承和元编程。在本文中,我们将解析四种强大的模式:Visitor、Strategy、State 和 CRTP——并附有真实代码示例以及何时使用它们的说明。
\n\n1. Visitor 模式——无需修改类即可扩展功能
\n\nVisitor 模式允许在不修改类本身的情况下向类层次结构添加新操作。当您拥有稳定的对象结构但处理算法经常变化时,这尤其有用。
\n\n示例:处理几何图形
\n\n#include <iostream>\n#include <vector>\n#include <memory>\n\n// 前向声明\nclass Circle;\nclass Rectangle;\n\n// 抽象访问者\nclass Visitor {\npublic:\n virtual void visit(Circle& circle) = 0;\n virtual void visit(Rectangle& rectangle) = 0;\n virtual ~Visitor() = default;\n};\n\n// 抽象元素\nclass Shape {\npublic:\n virtual void accept(Visitor& visitor) = 0;\n virtual ~Shape() = default;\n};\n\n// 具体元素\nclass Circle : public Shape {\npublic:\n double radius;\n explicit Circle(double r) : radius(r) {}\n void accept(Visitor& visitor) override {\n visitor.visit(*this);\n }\n};\n\nclass Rectangle : public Shape {\npublic:\n double width, height;\n Rectangle(double w, double h) : width(w), height(h) {}\n void accept(Visitor& visitor) override {\n visitor.visit(*this);\n }\n};\n\n// 具体访问者——计算面积\nclass AreaVisitor : public Visitor {\npublic:\n double totalArea = 0.0;\n void visit(Circle& circle) override {\n totalArea += 3.14159 * circle.radius * circle.radius;\n }\n void visit(Rectangle& rectangle) override {\n totalArea += rectangle.width * rectangle.height;\n }\n};\n\nint main() {\n std::vector<std::unique_ptr<Shape>> shapes;\n shapes.push_back(std::make_unique<Circle>(5.0));\n shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));\n\n AreaVisitor areaCalc;\n for (auto& shape : shapes) {\n shape->accept(areaCalc);\n }\n std::cout << "Total area: " << areaCalc.totalArea << std::endl;\n return 0;\n}\n\n\n何时使用:当需要对复杂层次结构中的对象执行不同操作而不修改其代码时。缺点——添加新类型需要修改所有访问者。
\n\n2. Strategy 模式——灵活地动态切换算法
\n\nStrategy 封装了一组可互换的算法,并允许在运行时替换它们。在 C++ 中,这通常通过 std::function 或虚类来实现。
示例:数据排序系统
\n\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <memory>\n#include <functional>\n\n// 使用策略的上下文\nclass Sorter {\nprivate:\n std::function<void(std::vector<int>&)> strategy_;\npublic:\n explicit Sorter(std::function<void(std::vector<int>&)> strategy)\n : strategy_(std::move(strategy)) {}\n\n void setStrategy(std::function<void(std::vector<int>&)> newStrategy) {\n strategy_ = std::move(newStrategy);\n }\n\n void sort(std::vector<int>& data) {\n if (strategy_) {\n strategy_(data);\n }\n }\n};\n\n// 具体策略\nvoid bubbleSort(std::vector<int>& da