Force all classes to implement / override a 'pure virtual' method in multi-level inheritance hierarchy

I found one mechanism, where at least we are prompted to announce the overridden method explicitly. It's not the perfect way though.

Suppose, we have few pure virtual methods in the base class B:

class B {
  virtual void foo () = 0;
  virtual void bar (int) = 0;
};

Among them, suppose we want only foo() to be overridden by the whole hierarchy. For simplicity, we have to have a virtual base class, which contains that particular method. It has a template constructor, which just accepts the type same as that method.

class Register_foo {
  virtual void foo () = 0; // declare here
  template<typename T>  // this matches the signature of 'foo'
  Register_foo (void (T::*)()) {}
};
class B : public virtual Register_foo {  // <---- virtual inheritance
  virtual void bar (int) = 0;
  Base () : Register_foo(&Base::foo) {}  // <--- explicitly pass the function name
};

Every subsequent child class in the hierarchy would have to register a foo inside its every constructor explicitly. e.g.:

struct D : B {
  D () : Register_foo(&D::foo) {}
  virtual void foo () {};
};

This registration mechanism has nothing to do with the business logic. Though, the child class can choose to register using its own foo or its parent's foo or even some similar syntax method, but at least that is announced explicitly.


What you're basically asking for is to require that the most derived class implement the functiom. And my question is: why? About the only time I can imagine this to be relevant is a function like clone() or another(), which returns a new instance of the same type. And that's what you really want to enforce, that the new instance has the same type; even there, where the function is actually implemented is irrelevant. And you can enforce that:

class Base
{
    virtual Base* doClone() const = 0;
public:
    Base* clone() const
    {
        Base* results = doClone();
        assert( typeid(*results) == typeid(*this) );
        return results;
    }
}

(In practice, I've never found people forgetting to override clone to be a real problem, so I've never bothered with something like the above. It's a generally useful technique, however, anytime you want to enforce post-conditions.)


In your example, you have not declared D::foo pure; that is why it does not need to be overridden. If you want to require that it be overridden again, then declare it pure.

If you want to be able to instantiate D, but force any further derived classes to override foo, then you can't. However, you could derive yet another class from D that redeclares it pure, and then classes derived from that must override it again.