Ok: here´s my problem: I have a base composit class which accepts a visitor an then iterates over its nodes. Works like a charm. But then, I have to used a derived from this composit and recognized that I have to override the "accept()" method in the derived class to have correct double dispatching (which I did not understand).
This brings out two flaws: first, I have to break the hidden structure of the base, and second, I have to duplicate code. To clearify, here´s my pseudo-code:
struct Visitor
{
void visit( BaseComposit*) { throw( "not expected"); };
void visit( DerivedComposit*) { throw( "ok"); };
};
class BaseComposit
{
private:
std::vector< BaseComposit*> nodes;
public:
virtual void accept( Visitor* v)
{
v->visit( this);
for( int i = 0; i < nodes.size(); i++)
nodes[ i]->accept( v);
}
};
class DerivedComposit : public BaseComposit
{
public:
};
Any ellegant solution on that ? Thank you !
Edit: added "virtual" to "accept()" to make it more precise...
Not really. That's what makes the visitor pattern a bit of a pain. Though you could mitigate the duplication a bit with the help of a template:
Now the duplication that
accept
must incur is smaller.Also, as @Oliv pointed out, your example really ought to have
accept
be a virtual function. Otherwise the whole thing won't work.If you feel really adventurous, you can introduce a macro to ease the "injection" of
accept
into each class. Like so:But you'd still need to use it in each derived class to make the definition appear.
The semi-colon is allowed by a curious feature of the C++ grammar. So I suppose one may argue the above looks "natural".