美文网首页
C++11访问者模式展示

C++11访问者模式展示

作者: FredricZhu | 来源:发表于2021-07-18 06:29 被阅读0次

    题目


    image.png

    题目作者把accept和visit方法写反了,但是这不影响做题。
    你也反着写就行了。
    就是看着有点别扭。
    这里的实现方式是传统的双向转发方式。
    就是每个被访问对象有一个accept方法,接收访问者的访问。
    访问对象有一堆visit方法,可以访问各种对象。[我是按正常的思路来说的,和代码刚好相反。]
    这是这23种中最复杂的一个模式了。
    因为它涉及到类层级的遍历。

    程序代码如下,

    #include <string>
    #include <sstream>
    using namespace std;
    
    struct Value;
    struct AdditionExpression;
    struct MultiplicationExpression;
    
    struct ExpressionVisitor
    {
       virtual void accept(Value& e) = 0;
       virtual void accept(AdditionExpression& ae) = 0;
       virtual void accept(MultiplicationExpression& me) = 0;
    };
    
    struct Expression
    {
      virtual void visit(ExpressionVisitor& ev) = 0;
    };
    
    struct Value : Expression
    {
      int value;
    
      Value(int value) : value(value) {}
      
      void visit(ExpressionVisitor& ev) {
          ev.accept(*this);
      }
    };
    
    struct AdditionExpression : Expression
    {
      Expression &lhs, &rhs;
    
      AdditionExpression(Expression &lhs, Expression &rhs) : lhs(lhs), rhs(rhs) {}
      
      void visit(ExpressionVisitor& ev) {
          ev.accept(*this);
      }
    };
    
    struct MultiplicationExpression : Expression
    {
      Expression &lhs, &rhs;
    
      MultiplicationExpression(Expression &lhs, Expression &rhs)
        : lhs(lhs), rhs(rhs) {}
        
      void visit(ExpressionVisitor& ev) {
          ev.accept(*this);
      }
    };
    
    struct ExpressionPrinter : ExpressionVisitor
    {
       void accept(Value& e) override {
           oss << e.value;    
       }
       
       // 所有加法都需要()
       void accept(AdditionExpression& ae) override {
           oss << "(";
           ae.lhs.visit(*this);
           oss << "+";
           ae.rhs.visit(*this);
           oss << ")";
       }
       
       // 乘法只有右值是加法的时候需要()
       void accept(MultiplicationExpression& me) override {
           bool need_braces = (typeid(me.rhs) == typeid(AdditionExpression));
           if(need_braces) oss << "(";
           me.lhs.visit(*this);
           oss << "*";
           me.rhs.visit(*this);
           if(need_braces) oss << ")";
       }
        
    
      string str() const { 
            return oss.str();
      }
      
      private:
        ostringstream oss;
    };
    

    相关文章

      网友评论

          本文标题:C++11访问者模式展示

          本文链接:https://www.haomeiwen.com/subject/mrkopltx.html