代码之家  ›  专栏  ›  技术社区  ›  Jayendra Parmar

正确执行运算符重载和多态性

  •  -1
  • Jayendra Parmar  · 技术社区  · 7 年前

    我有两个用于string和int的包装器类,一个用于表示二进制操作和重载运算符 << 以字符串格式写入它们。不幸的是,我不能超载 << 没有 friend virtual 不能使用 具有 事实上的 !!

    #include <iostream>
    #include <string>
    
    class AST {};
    class expr: public AST {};
    
    class operator_: public AST {};
    
    class BinOp: public expr {
    private:
      expr *_left;
      expr *_right;
      operator_ *_op;
    public:
      BinOp(expr *p_left, expr *p_right, operator_ *p_op):_left(p_left),_right(p_right),_op(p_op) {}
      friend std::ostream &operator<< (std::ostream &out, const BinOp &binop) {
        out << (binop._left) << " " << (binop._op) << " " << (binop._right);
      }
    };
    
    class LShift: public operator_ {
    public:
      LShift() {}
      friend std::ostream &operator<< (std::ostream &out, const LShift &lshift) {
        out << "<<";
      }
    };
    
    class Name: public expr {
    private:
      std::string _id;
    public:
      Name(std::string p_id) { _id = p_id; }
      friend std::ostream &operator<< (std::ostream &out, const Name &name) {
        out << name._id;
      }
    };
    
    class Num: public expr {
    private:
      int n;
    public:
      Num(int p_n) { n = p_n; }
      friend std::ostream &operator<< (std::ostream &out, const Num &num) {
        out << num.n;
      }
    };
    
    int main() {
    
      auto name = Name("x");
      auto num  = Num(5);
      auto lshift = LShift();
      auto binop = BinOp(&name, &num, &lshift);
    
      std::cout << binop << '\n';
    
      return 0;
    }
    

    所以上面提到的程序输出指针,

    0x7ffd05935db0 0x7ffd05935d8b 0x7ffd05935d8c
    

    x << 5
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Sebastian Redl    7 年前

    但我要说的是,流插入操作符是一个例外。

    解决方案是重载操作符一次,并将其转发到更易于重写的函数。

    class AST {
    public:
      virtual void print(std::ostream& s) const = 0;
      virtual ~AST() {} // you probably want this one too
    };
    
    // no need for friendliness
    std::ostream& operator <<(std::ostream& s, const AST& node) {
      node.print(s);
      return s;
    }
    

    print 每个类的重写。

    但我也觉得有必要指出 AST 在AST中,树中的单个节点。运算符是表达式的一部分。整棵树都不一样。

    您应该有单独的层次结构根 operator_ expr

    推荐文章