2010-01-15 4 views
2

Je n'arrive pas à appliquer le modèle de visiteur pour un interpréteur en C++. Le code suivant produit (+) plutôt que ((1 + 2) +3) selon vos besoins:Utilisation du modèle de visiteur pour un interpréteur en C++

class ExpVisitor{ 
public: 
    virtual void visit(class Add*)=0; 
    virtual void visit(class Int*)=0; 
}; 

class Exp{ 
public: 
    virtual void accept(ExpVisitor *v){}; 
}; 

class Add : public Exp{ 
public: 
    Exp e1,e2; 
    Add(Exp in1,Exp in2){ 
     e1=in1; 
     e2=in2; 
    } 
    void accept(ExpVisitor *v){ 
     v->visit(this); 
    } 
}; 

class Int : public Exp{ 
public: 
    int val; 
    Int(int v){ 
     val=v; 
    } 
    void accept(ExpVisitor *v){ 
     v->visit(this); 
    } 
}; 

class PrintExp : public ExpVisitor{ 
public: 
    void visit(Add *e){ 
     cout << '('; 
     (e->e1).accept(this); 
     cout << '+'; 
     (e->e2).accept(this); 
     cout << ')'; 
    } 
    void visit(Int *e){ 
     cout << e->val; 
    } 
}; 


int main(){ 
    Add e=Add(Add(Int(1),Int(2)),Int(3)); 
    PrintExp p; 
    e.accept(&p); 
    cout << endl; 
} 

Le problème, bien sûr, est que Exp :: accept est appelé au lieu de partir de Ajouter ou Int . Cependant, je ne peux pas faire accepter purement virtuel puisque Ajouter possède deux membres e1 et e2 de type Exp. Comment puis-je corriger cet exemple?

+0

Hmm, http://en.wikipedia.org/wiki/Interpreter_pattern semble pertinent ici. –

Répondre

3

Vous devez créer les champs dans Ajouter des pointeurs aux instances de Exp. Ensuite, vous pouvez rendre la méthode accept virtuelle. Bien sûr, vous devez gérer la mémoire. Le plus simple serait d'utiliser des ptrs intelligents.

0

Il y a un autre problème dans Ajouter (Exp IN1, IN2 Exp) - IN1, IN2 ou qui devraient être des références (pointeurs, en plus de ce que MPG a)

0

Merci pour l'aide. Pour référence, le code de travail est

#include<iostream> 
using namespace std; 

class ExpVisitor{ 
public: 
    virtual void visit(class Add*)=0; 
    virtual void visit(class Int*)=0; 
}; 

class Exp{ 
public: 
    virtual void accept(ExpVisitor *v)=0; 
}; 

class Add : public Exp{ 
public: 
    Exp *e1,*e2; 
    Add(Exp *in1,Exp *in2){ 
     e1=in1; 
     e2=in2; 
    } 
    void accept(ExpVisitor *v){ 
     v->visit(this); 
    } 
}; 

class Int : public Exp{ 
public: 
    int val; 
    Int(int v){ 
     val=v; 
    } 
    void accept(ExpVisitor *v){ 
     v->visit(this); 
    } 
}; 

class PrintExp : public ExpVisitor{ 
public: 
    void visit(Add *e){ 
     cout << '('; 
     (e->e1)->accept(this); 
     cout << '+'; 
     (e->e2)->accept(this); 
     cout << ')'; 
    } 
    void visit(Int *e){ 
     cout << e->val; 
    } 
}; 

int main(){ 
    Exp *i1=new Int(1); 
    Exp *i2=new Int(2); 
    Exp *i3=new Int(3); 
    Exp *e1=new Add(i1,i2); 
    Exp *e2=new Add(e1,i3); 

    PrintExp p; 
    e2->accept(&p); 
    cout << endl; 

    delete i1,i2,i3,e1,e2; 
} 
Questions connexes