Skip to content

Instantly share code, notes, and snippets.

@pvicente
Created August 5, 2012 18:56
Show Gist options
  • Save pvicente/3266682 to your computer and use it in GitHub Desktop.
Save pvicente/3266682 to your computer and use it in GitHub Desktop.
Visitor.cpp
//============================================================================
// Name : Visitor.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
using namespace std;
class VisitableElement;
class ElementA;
class ElementB;
class Visitor
{
public:
virtual bool visit(VisitableElement &e){std::cout<<"Not implemented"<<std::endl; return false;}
virtual bool visit(ElementA &e){return visit(reinterpret_cast<VisitableElement&>(e));}
virtual bool visit(ElementB &e){return visit(reinterpret_cast<VisitableElement&>(e));}
virtual ~Visitor(){}
};
class VisitableElement
{
private:
std::string _name;
public:
VisitableElement(const std::string &name){_name = name;}
const std::string& getName() const {return _name;}
virtual void accept(Visitor &v)=0;
virtual ~VisitableElement(){}
};
class ElementA: public VisitableElement
{
public:
ElementA():VisitableElement("ElementA"){}
void accept(Visitor &v){v.visit(*this);}
};
class ElementB: public VisitableElement
{
public:
ElementB():VisitableElement("ElementB"){}
void accept(Visitor &v){v.visit(*this);}
};
class PrintVisitor:public Visitor
{
public:
bool visit(ElementA &e)
{
std::cout<<e.getName()<<std::endl;
return true;
}
};
int main() {
ElementA a;
ElementB b;
PrintVisitor v;
a.accept(v);
b.accept(v);
return 0;
}
@akrastev
Copy link

Hey Pedro,

While randomly browsing around, I saw your gist.
Here are couple of suggestions:

  • Nit: `std::' is unnecessary everywhere because of the using directive.

  • Nit: unused variables `e' in Visitor::visitor overloads.
    This would be seen with -Wall and -Werror.

    Remedies:

    • (void) e;
    • /* comment e */ in argument list
    • leave the argument unnamed
  • reinterpret_cast looks ugly.

    Why don't we just have:

    class Visitor
    {
    public:
    virtual bool visit(VisitableElement &) { return NotImplemented(); }
    virtual bool visit(ElementA &) { return NotImplemented(); }
    virtual bool visit(ElementB &) { return NotImplemented(); }
    virtual ~Visitor() {}

    private:
    bool NotImplemented () const { cout << "Not Implemented" << endl; return false; }
    };

Regards,
Asen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment