Reputation: 5947
Overwrite a derived function behaviour while still calling the same function of it's parent, see C::foo() for example.It still have the behaviour of A::foo but extended it. Is it too simple to be a pattern ?
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;
}
Upvotes: 0
Views: 173
Reputation: 254631
There's no requirement for a design element to be complicated to be called a "pattern".
However, there is a requirement that it be useful; that it makes it easier to produce correct, coherent, efficient and flexible designs. Implementing useful functionality in a base class, and then placing a burden on derived classes to remember to invoke it manually, doesn't really meet that requirement, and so I'd be tempted to label it an "anti-pattern". Adding an intermediate base class, and expecting derived class implementors to figure out which override(s) they actually want, is more along the lines of a "confusing mess".
If you want a bona fide pattern (described using capital letters in a famous book) for this situation, then the Template Method might be appropriate - the base class contains a non-virtual function which performs some common functionality, delegating part of the work to private, pure virtual functions that can be overridden. Personally, I'd go one step further and delegate to a separate class, since I like to give each class a single responsibility and avoid inheriting from anything except abstract interfaces, giving something along the lines of:
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");
}
};
Upvotes: 2
Reputation: 146968
By "Simple but useful pattern" you mean "Language feature". You can't just use a language feature once and call it a pattern. It's not a pattern. It's just you using a language feature. I mean, congratulations, I also think that using language features is an important way to go about constructing programs in a language, but, it's a long way from any pattern anything.
Upvotes: 3