c++polymorphismc++17dynamic-binding

What if I must override a non-virtual member function


Say we have a library which provides a class

struct Base { int foo() { return 42; } };

I cannot change that class. 99% of the people never want to override foo, hence it has not been made virtual by the library designers. But I need to override it:

struct MyClass : Base { int foo() { return 73; } };

Even worse, the library has interfaces accepting pointers to Base. I want to plug in MyClass, but of course, since foo is not virtual, the code behind the interface always calls Base::foo. I want it to call MyClass::foo.

What can I do about it? Is there a common pattern to make Base::foo appear to be virtual?

In reality, Base::foo is QAbstractProxyModel::sourceModel. I'm implementing a ProxyChain, to abstract many proxy models to a single one. QAbstractProxyModel::setSourceModel is virtual, but QAbstractProxyModel::sourceModel isn't and that makes a lot of trouble.

void ProxyChain::setSourceModel(QAbstractItemModel* source_model)
{
  for (auto* proxy : m_proxies) {
    proxy->setSourceModel(source_model);
    source_model = proxy;
  }
  QIdentityProxyModel::setSourceModel(source_model);
}

QAbstractItemModel* ProxyChain::sourceModel() const
{
  return m_proxies.front()->sourceModel();
}


Solution

  • What can I do about it?

    Nothing.

    This is why guidelines tell us to use virtual if we want other people to be able to "pretend" that their classes are versions of our classes.

    The author of Base did not do that, so you do not have that power.

    That's it.