Just an example I have used in the past. Protected methods are great for providing implementation-specific functions, whilst also allowing the base class to properly track things. Consider a base class that provides an overridable initialization function, but must also have state to determine if initialized:
class Base
{
private:
bool m_bInitialized;
public:
virtual void Initialize() = 0;
void setInitialized() { m_bInitialized = true; };
bool isInitialized() const { return m_bInitialized; };
}; // eo class Base
All is well and good here. Except when a derived class doesn't bother to call setInitialized()
not least the fact that anybody can call it (we could make this protected here, and another reason to use protected methods!). I much prefer a class that makes use of virtual protected members:
class Base
{
private:
bool m_bInitialized;
protected:
virtual void InitializeImpl() = 0;
public:
void Initialize()
{
InitializeImpl();
m_bInitialized = true;
}; // eo Initialize
bool isInitialized() const { return m_bInitialized; };
}; // eo class Base
In our new class, all initialization is still delegated to the derived class. Provided an exception as been thrown, we maintain the "this class is initialized" contract that our method says will happen.