#include "iostream"

class Logger
{
public:
    Logger(std::string name) : name_(name) {}
    void log(std::string msg) { std::cout << name_ << ": " << msg << std::endl; }
private:
    std::string name_;
};

template<typename T>
class LoggerImp : public Logger
{
public:
    LoggerImp(const std::string& n) : Logger(n) {}
};

class B : private LoggerImp<B>
{
    typedef LoggerImp<B> LL;
public:
    B() : LoggerImp<B>("Class B" ) {}
    void doSomethingInB()
    {
        LL::log("B doing something");
    }
};

class C : public B, private LoggerImp<C>
{
    typedef LoggerImp<C> LL;
public:
    C() : LoggerImp<C>("Class C" ) {}
    void doSomethingInC()
    {
        LL::log("C doing something");
    }
};

int main()
{
    B* b = new B();
    C* c = new C();

    b->doSomethingInB();

    c->doSomethingInC();
    c->doSomethingInB();

    return 0;
}