我正在寻找避免"召唤超级"代码气味的方法.当重新实现该函数时,需要子类来调用超类的虚函数版本时,会出现此代码异味.
class Base
{
public:
virtual void foo(){ ... }
}
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
Run Code Online (Sandbox Code Playgroud)
如果继承只有一层深,我可以使用模板方法
class Base
{
public:
void foo(){ ... ; foo_impl(); }
protected:
virtual void foo_impl(){}
}
class Derived : public Base
{
protected:
virtual void foo_impl(){ ... }
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我需要继承Derived,我会回到我开始的地方.
我正在考虑注册方法.
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(){ ... }
}
Run Code Online (Sandbox Code Playgroud)
有更标准的方法吗?这种方法有任何问题或改进吗?
用于
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
Run Code Online (Sandbox Code Playgroud)
是IMO的最佳方法.我不确定你为什么会考虑"代码味道".
Base::foo().Base需要实现Base::foo(),那么公共代码就更好了Base::foo().派生类只需要进行调用.对于它的价值,我们在我的工作中使用了这种模式,并且已经证明它已经使用了20多年.