问题
According to http://www.thinkbottomup.com.au/site/blog/C%20%20_Mixins_-_Reuse_through_inheritance_is_good
But hang on a minute, none of this helps us plug into our Task Manager framework as the classes do not implement the ITask interface. This is where one final Mixin helps - a Mixin which introduces the ITask interface into the inheritance hierarchy, acting as an adapter between some type T and the ITask interface:
template< class T > class TaskAdapter : public ITask, public T { public: virtual void Execute() { T::Execute(); } virtual std::string GetName() { return T::GetName(); } };
Using the TaskAdapter is simple - it's just another link in the chain of mixins.
// typedef for our final class, inlcuding the TaskAdapter<> mixin typedef public TaskAdapter< LoggingTask< TimingTask< MyTask > > > task; // instance of our task - note that we are not forced into any heap allocations! task t; // implicit conversion to ITask* thanks to the TaskAdapter<> ITask* it = &t; it->Execute();
Why is TaskAdapter
needed, when ITask
is implemented by MyTask
? Also if ITask
is not abstract, it may lead to diamond problem.
回答1:
That's a very cool and interesting article.
In the final Mixin example, the MyTask
class is not derived from ITask
. Which means it can't be cast to an ITask
pointer which is being done at the very end.
In that example, I believe you could derive MyTask
from ITask
. But I think the author wanted to illustrate that you can even decouple the MyTask
class by using the TaskAdapter
.
来源:https://stackoverflow.com/questions/34193264/mixin-and-interface-implementation