0

覆盖派生函数的行为,同时仍调用其父函数的相同函数,例如参见 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;
}
4

2 回答 2

3

“简单但有用的模式”是指“语言特征”。您不能只使用一次语言功能并称其为模式。这不是一种模式。只是您使用了语言功能。我的意思是,恭喜,我也认为使用语言特性是用一种语言构建程序的重要方法,但是,它与任何模式都相去甚远。

于 2012-09-14T11:32:59.620 回答
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");
    }
};
于 2012-09-14T12:09:33.323 回答