在仍然调用它的父元素的相同函数时覆盖派生函数行为,例如参见C :: foo()。它仍然具有A :: foo的行为但是对它进行了扩展。成为一个模式太简单了吗?
class A
{
public:
virtual ~A() {}
virtual void foo(){ MSG("A::foo");}
};
class B : public A
{
public:
virtual void foo(){ MSG("B::foo");}
};
class C : public B
{
public:
virtual void foo(){
A::foo(); //here still have the behaviour of A::foo but extended it
MSG("C::foo");
}
};
void callFoo(A* p)
{
p->foo();
}
int main()
{
boost::scoped_ptr<A> myPtr(new A());
callFoo(myPtr.get());
myPtr.reset(new B());
callFoo(myPtr.get());
myPtr.reset(new C());
callFoo(myPtr.get());
return 0;
}
答案 0 :(得分:3)
“简单但有用的模式”是指“语言功能”。您不能只使用一次语言功能并将其称为模式。这不是一种模式。只是你使用语言功能。我的意思是,恭喜,我也认为使用语言功能是用语言构建程序的重要方法,但是,它与任何模式都有很长的路要走。
答案 1 :(得分:2)
不需要将设计元素复杂化为“模式”。
然而,要求它是有用的;它可以更容易地生成正确,连贯,高效和灵活的设计。在基类中实现有用的功能,然后对派生类施加负担以记住手动调用它,并不真正满足该要求,因此我很想将其标记为“反模式”。添加一个中间基类,并期望派生类实现者找出他们实际想要的覆盖,更像是一个“令人困惑的混乱”。
如果你想要一个真正的模式(在着名的书中用大写字母描述),那么模板方法可能是合适的 - 基类包含一个非虚拟函数,它执行一些常见功能,将部分工作委托给可以覆盖的私有,纯虚拟功能。就个人而言,我更进一步,委托给一个单独的类,因为我喜欢给每个类一个单一的责任,并避免继承除抽象接口之外的任何东西,给出类似的东西:
class FooInterface {
public:
virtual ~FooInterface() {}
virtual void foo() = 0;
};
class A {
public:
void foo(FooInterface & impl) {
MSG("A::foo"); // Happens whatever the implementation does
impl.foo();
}
};
class C : public FooInterface {
virtual void foo() {
// We don't have to worry about A at all
MSG("C::foo");
}
};