I'm looking for ways to avoid the "call super" code smell. This code smell is present when a subclass is required to invoke the super class's version of a virtual function when re-implementing that function.
class Base
{
public:
virtual void foo(){ ... }
}
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
If inheritance went only a single layer deep, I could use the template method
class Base
{
public:
void foo(){ ... ; foo_impl(); }
protected:
virtual void foo_impl(){}
}
class Derived : public Base
{
protected:
virtual void foo_impl(){ ... }
}
But if I need to subclass Derived, I'm back where I started.
I'm considering a registration approach.
class Base
{
public:
Base()
{
_registerCallback( [this](){ _baseFoo(); } );
}
void foo()
{
for( auto f : _callbacks )
f();
}
protected:
void registerCallback( std::function<void()> f )
{
_callbacks << f;
}
private:
void _baseFoo() { ... }
std::list< std::function<void()> > _callbacks;
}
class Derived : public Base
{
public:
Derived()
{
_registerCallback( [this](){ _derivedFoo(); } );
}
private:
virtual void _derivedFoo(){ ... }
}
Is there a more standard approach? Any problems with or improvements to this approach?
Aucun commentaire:
Enregistrer un commentaire