3
votes

I have an abstract base class with one purely virtual method:

class Base
{
public:
    virtual void update() = 0;
};

Is there any way I could create a class that inherits from Base, overrides the update method, but still forces its children to implement an update method? Like this:

class Base2 : public Base
{
public:
    void update() override
    {
        if(bSomeCondition)
        {
            update(); //Calls child's update method
        }
    }
    virtual void update() = 0; // Obviously not like this
};

I know I could create two new purely virtual methods with slightly different names in Base2, and just override those in child classes, but I would really like to keep these method names if that would be possible.

I'm guessing this isn't possible?

2
So, it is possible, but it's unclear what you hope to achieve. When would the intermediate function be called, and why?Useless
I suspect you might be better off making a Base0 that both Base and Base2 are child classes that override the function of Base0Abel
The usual approach is to derive classes directly from Base, not from Base2. In other words, don't derive from concrete (instantiable) classes. C++11 and later, that can be enforced by tagging Base2 as final.Peter
"// Obviously not like this" -- well, obviously the line stating "obviously" is the obvious way to do it. It's the inline definition above the "obviously" line that is obviously the problem. :) Have I mentioned recently that "obviously" more often qualifies false statements than true ones? Always doubt yourself whenever you find yourself saying something is obvious!JaMiT

2 Answers

2
votes

You can provide a definition for a pure virtual function, just not inline.

class Base2 : public Base
{
public:
    void update() override = 0;
};

void Base2::update() // Base2 is abstract regardless of this
{
    if(bSomeCondition)
    {
        update(); 
    }
}

However, this is not useful with the current implementation of Base2::update. Because a child class must override it anyway, Base2 version will not be called unless used explicitly:

class Child: public Base2
{
public:
    void update() override
    {
        Base2::update(); //infinite recursion with such implementation
    }
};

// the other way would be to require calling it explicitly at call site

std::unique_ptr<Base2> ptr = std::make_unique<Child>();
ptr->Base2::update(); 

What you should do is to provide an implementation and another pure virtual function (possibly protected) to be called:

class Base2 : public Base
{
public:
    void update() override;

protected:
    virtual void doStuff() = 0;
};

void Base2::update()
{
    if(bSomeCondition)
    {
        doStuff(); //Calls child's update method
    }
}
-1
votes

No, it is not possible and in my opinion it would be very illegible.