Upon experimenting with the Visitor Pattern in C++, I have come to a silly problem with regards to implementing a derived interface. I suspect that I do not know how to formulate the question correctly, as I have not found a solution to this elsewhere.
I have the following base struct:
struct Visitor {
virtual void visit(const Resources) = 0;
virtual void visit(const Population) = 0;
};
I wish to declare a couple of concrete implementations of Visitor along with some extra functionality. This is how I want my declarations to look like:
struct EndVisitor : public Visitor{
virtual bool hasEnded();
};
struct SetupVisitor : public Visitor{
};
struct ScoreVisitor : public Visitor{
virtual unsigned int getScore();
};
When defining, say for instance ScoreVisitor, the IDE and compiler recognizes the extra function declarations in ScoreVisitor:
unsigned int ScoreVisitor::getScore() {
return total;
}
However, implementing the Visitor functions are not recognized by the compiler or IDE (Funtion 'visit' not declared in class 'ScoreVisitor'
):
void ScoreVisitor::visit(const Resources resources) {
total += resources.score;
}
void ScoreVisitor::visit(const Population population) {
total += population.score;
}
If I declare ScoreVisitor repeating the Visitor functions, the code compiles, however this leaves me with a lot of copy-pasted code in all specialized declarations of Visitor, which I wish to avoid. This is not how I want my declarations to look like:
struct ScoreVisitor : public Visitor{
virtual void visit(const Resources);
virtual void visit(const Population);
virtual unsigned int getScore();
};
How do I declare specialized versions of Visitor without having to copy-paste all the functionality that Visitor already declares?
There is no way to avoid having to declare methods you are overriding from a base class in a derived class. This is the way the language is. Typically people group functionality into some form of inheritance hierarchy to expose common functionality.
NOTE a couple of syntax related matters, virtual
is optional for derived classes (a function with a similar signature is virtual by default), since C++11, some folks have taken to using override
(I fall into this category too) as it will catch - at compile time - any cases where in a derived class a method is expected to be virtual, but in a base class it is not declared as such.
I'm sure the above is an example, but it's critical you don't forget a virtual destructor in the base class!