欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 《C++20设计模式》访问者模式

《C++20设计模式》访问者模式

2024/10/24 22:23:30 来源:https://blog.csdn.net/Ten_years_star/article/details/140307638  浏览:    关键词:《C++20设计模式》访问者模式

文章目录

  • 一、前言
    • 1、如何学好访问者模式,前提条件肯定是要知道`访问者模式是干什么的`。
    • 2、访问者模式实现方式
  • 二、经典访问者模式
    • 1、UML类图
    • 2、实现
  • 三、使用std::variant和std::visit的实现访问者模式
    • 1、UML类图
    • 2、实现

一、前言

1、如何学好访问者模式,前提条件肯定是要知道访问者模式是干什么的

扩展原有类族的功能(形象点来说就是系统升级),符合开闭原则,对一类代码都进行扩展

2、访问者模式实现方式

这里介绍两种,为什么是两种而不是一种呢?因为真的各有各的优点,很难取舍!🫠

  • 经典访问者模式
  • 使用std::variant和std::visit的实现访问者模式

相关代码可以在这里,如有帮助给个star!AidenYuanDev/design_patterns_in_modern_Cpp_20

二、经典访问者模式

类族每个类都添加accept()函数,传入自身this,调用访问者,然后经由访问者实现新功能。

1、UML类图

经典访问者模式

2、实现

#include <iostream>
#include <memory>
using namespace std;class Cpu;
class Memory;class Visitor {
public:virtual void visit_cpu(const Cpu& cpu) const = 0;virtual void visit_memory(const Memory& memory) const = 0;
};class Computer {
public:virtual void accept(const Visitor& visitor) const = 0;virtual void show() const = 0;
};class Cpu : public Computer {
public:void accept(const Visitor& visitor) const override {visitor.visit_cpu(*this);}void show() const override {cout << "老旧Cpu";}
};class Memory : public Computer {
public:void accept(const Visitor& visitor) const override {visitor.visit_memory(*this);}void show() const override {cout << "老旧Memory";}};class Visitor_Rog : public Visitor {
public:void visit_cpu(const Cpu& cpu) const override {cpu.show();   cout << "升级为新Rog Cpu" << endl;}void visit_memory(const Memory& memory) const override {memory.show();cout << "升级为Rog Memory" << endl;}
};int main(){auto cpu = make_unique<Cpu>();auto memory = make_unique<Memory>();auto visitor_rog = make_unique<Visitor_Rog>();cpu->accept(*visitor_rog);memory->accept(*visitor_rog);return 0;
}

三、使用std::variant和std::visit的实现访问者模式

这种方法利用了 C++17 引入的新特性,可以在某些情况下提供更简洁和高效的实现。所以如果可以支持C++17那么我还是推荐用这个(因为真的简单和方便)

1、UML类图

variant实现访问者模式

2、实现


#include <iostream>
#include <vector>
#include <variant>
#include <string>// 定义元素类型
class Circle {
public:void draw() const { std::cout << "Drawing a circle\n"; }
};class Square {
public:void draw() const { std::cout << "Drawing a square\n"; }
};class Triangle {
public:void draw() const { std::cout << "Drawing a triangle\n"; }
};// 使用 std::variant 定义可能的元素类型
using Shape = std::variant<Circle, Square, Triangle>;// 定义访问者
class DrawVisitor {
public:void operator()(const Circle& c) const { c.draw(); }void operator()(const Square& s) const { s.draw(); }void operator()(const Triangle& t) const { t.draw(); }
};class AreaVisitor {
public:double operator()(const Circle&) const { std::cout << "Calculating circle area\n";return 3.14; // 简化计算}double operator()(const Square&) const { std::cout << "Calculating square area\n";return 4.0; // 简化计算}double operator()(const Triangle&) const { std::cout << "Calculating triangle area\n";return 1.5; // 简化计算}
};// 使用示例
int main() {std::vector<Shape> shapes = {Circle(), Square(), Triangle()};// 使用 DrawVisitorstd::cout << "Drawing shapes:\n";for (const auto& shape : shapes) {std::visit(DrawVisitor(), shape);}// 使用 AreaVisitorstd::cout << "\nCalculating areas:\n";for (const auto& shape : shapes) {double area = std::visit(AreaVisitor(), shape);std::cout << "Area: " << area << "\n";}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com