Any functions that the base class needs to call that will be defined in the child class must also be defined in the base class. They should be defined "virtual" so they can be overridden, and can even be "pure virtual" so they have to be defined in the child class.

So for any function in the child class that the base class needs to access, add this to the base class's definition (print.h):

virtual void write(unsigned char data) = 0;

The = 0 bit defines it as pure virtual, and any classes than inherit this class without defining their own copy of the void write(unsigned char) function will thrown an error.

Instead of pure virtual you can provide a default function that a child can override if they want to, which can be useful if most classes will work the same way (define it in the parent) but some want to do it differently (override it in the child), in which case you treat it like a normal class function but add the virtual tag.

The whole topic is called polymorphism and is an incredibly powerful system. It's discussed in detail here: http://www.cplusplus.com/doc/tutorial/polymorphism/