Mixins

What is a Mixin?

This is mixin as Jannis Smaragdakis calls it.


// Mixin

template <class Base>
class Mixin : public Base  { ... };

class Base { ... };

The interesting thing is, that in normal object-oriented style base is always implemented before derived. Here we can implement inheritance delaying the definition of the base.


//
//  suppose Graph has succ_node() and succ_edge()
//
template <class Graph>
class Counting : public Graph
{
public:
    Counting() : nodes_visited(0), edges_visited(0)  { }
    node succ_node( node v)
    {
        ++nodes_visited;
        return Graph::succ_node(v);
    }
    node succ_edge( node v)
    {
        ++edges_visited;
        return Graph::succ_edge(v);
    }
private:
    int nodes_visited;
    int edges_visited;
};

Counting< Ugraph >  counted_ugraph;
Counting< Dgraph >  counted_dgraph;

Mixin issues

Be care with the lazy instantiation:


//
//  be care with lazy instantiation
//
template <class Sortable>
class WontWork : public Sortable
{
public:
    void sort(X x)
    {
        Sortable::srot(x);  // !!misspelled
    }
};
WontWork w;

If the client never calls w.sort there is no error message!

Liskov substitutional principle

In 1977 Barbara Liskov defined her substitutional principle: an object from the subtype can appear in every place where its supertype's objects can. That is one of the most fundamental rule in object-orientation: a derived object can appear everywhere the base object can.

The problem is, that this does not hold for mixins.


lass Base { ... };
class Derived : public base { ... };

template <class T> class Mixin : public T { ... };

Base        b;
Derived     d;

Mixin<Base>     mb;
Mixin<Derived>  md;

b  = d      // OK
mb = md;    // Error!

We have seen a similar situation with auto_ptr. The auto_ptr<Derived> does not konvertible to auto_ptr<Base>.