DeMarcus said:
Yes, you're right. I have to go through my code and see what I really
though when I designed it. But our solutions are quite close ain't
they? I mean, if we remove the inheritance of Interface from class Cafe
and change MakeCoffee to
class MakeCoffe : public Functor
{
public:
MakeCoffe( void* instance );
virtual void execute( void )
{
dynamic_cast<Cafe*>(instance)->makeCoffe( sugar, milk );
}
};
and change Thread::run() to
void run( Functor* functor )
{
functor->execute();
}
The point was to NOT inherit from something in the framework. Let me be more
explicit. You need a base functor class, say 'ThreadFunctor' that provides a
virtual method that's invoked by your threads (or eventually your thread pools
and other dispatch mechanisms, but let's not get ahead of ourselves). I usually
make that operator()(), but that's almost arbitrary in this context. Now, if you
want to invoke method 'doSomething' from class 'Whatever', you create a new
functor class, as follows:
class WhateverFunctor : public ThreadFunctor
{
public:
WhateverFunctor(Whatever & obj, int arg)
: m_obj(obj)
, m_arg(arg)
{
}
// other ctors, dtor, etc.
virtual void operator()()
{
m_obj.doSomething(arg);
}
private:
Whatever & m_obj;
int m_arg;
};
See? The original class, 'Whatever', doesn't get modified. It doesn't depend on
the threading framework and if you ever need to port it to another environment,
you can do it without maintaining different versions for the two (or more)
environments.
A test to see if inheritance is gratuitous is to ask if a class really IS a
variant of another. Is a coffee maker an interface? No. Is a coffee maker a
functor? No. If I want to bludgeon someone with a coffee maker, does that make a
coffee maker a mace? No.
Think of it another way. If I did want to use a coffee maker as an interface, a
mace, a lucky charm, and a decoration, would the class look like this?
class CoffeeMaker : public Interface, public Mace, public LuckyCharm, public
Decoration {};
It's extreme, but that's exactly what happens when someone inherits from a
totally unrelated class just to shoehorn the class into a particular usage.
Claudio Puviani