lundi 21 janvier 2019

Visitor pattern apply on shared_ptr or raw pointer?

I am working on a small compiler. Now i have a hierarchy system to express the Abstract Syntax Tree(AST).

class Ast{
public:
    // ...
}

class Expr : public Ast{
public:
    // ...
}

using ExprNode = shared_ptr<Expr>;

class BinaryOp : public Expr{
public:
    ExprNode lhs;
    ExprNode rhs;
}

All the class in the Ast hierarchy system use shared_ptr to manage their member(if needed), for example, the BinaryOp holds two member to express its operand.

I'd like to apply visitor pattern on the tree to produce IR code for the AST. My problem is, should the visitor accept raw pointer as parameter, or accept shared_ptr as parameter, which may import shared_from_this(consider the pros and cons)? If shared_ptr is need, should i use pass it by value or by reference?


Raw pointer

class AstVisitor{
public:
   virtual Ast* visit(Ast* ast);
   virtual Ast* visitBinaryOp(BinaryOp* binary){
      visit(binary->lhs.get());
      visit(binary->rhs.get());
      // ...
   }
}

class Ast{
public:
    virtual Ast* accept(AstVisitor& visitor);
}

class BinaryOp:{
public:
    virtual Ast* accept(AstVisitor& visitor) override{
        return visitor.visitBinaryOp(this);
    }
}

shared_ptr

using AstNode = shared_ptr<Ast>;
using BinaryOpNode = shared_ptr<BinaryOp>;
class AstVisitor{
public:
   virtual AstNode visit(AstNode ast);
   virtual AstNode visitBinaryOp(BinaryOpNode binary){
      visit(binary->lhs);
      visit(binary->rhs);
      // ...
   }
}

class Ast : public enable_shared_from_this<Ast>{
public:
    virtual AstNode accept(AstVisitor& visitor);
}

class BinaryOp:{
public:
    virtual AstNode accept(AstVisitor& visitor) override{
        return visitor.visitBinaryOp(static_pointer_cast<BinaryOp>(shared_from_this()));
    }
}

Aucun commentaire:

Enregistrer un commentaire