Search code examples
c++structvisitor-pattern

C++ struct implement derived interface


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?


Solution

  • 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!