Deriving with protected
makes the members of the base class inaccessible through a pointer to the derived class, and disallows the implicit conversion.
It seems to me that what you want is not to forbid access through the base class (interface), but rather through the derived class (concrete implementation):
class IHandler
{
public:
virtual int process_input(char input) = 0; //pure virtual
virtual std::string name() { return "IHandler"; } //simple implementation
};
class MyEngine : public IHandler
// ^^^^^^
{
protected: // <== Make the functions inaccessible from a pointer
// or reference to `MyEngine`.
virtual int process_input(char input) { return 0; } //override pure virtual
using IHandler::name; //use IHandler version
};
Here, in the derived class you basically override the visibility of the process_input
function, so that clients can only call them through a pointer or reference to the base class.
This way you will make this impossible:
MyEngine* ptr = new MyEngine();
ptr->process_input('a'); // ERROR!
std::cout << ptr->name(); // ERROR!
But this will be possible:
IHandler* ptr = new MyEngine();
ptr->process_input('a'); // OK
std::cout << ptr->name(); // OK