Apenas um exemplo que eu usei no passado. Os métodos protegidos são ótimos para fornecer funções específicas da implementação, além de permitir que a classe base rastreie corretamente as coisas. Considere uma classe base que fornece uma função de inicialização substituível, mas também deve ter estado para determinar se foi inicializada:
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
Tudo está bem aqui. Exceto quando uma classe derivada não se preocupa em chamar, setInitialized()
pelo menos, o fato de que alguém pode chamá-la (poderíamos tornar isso protegido aqui, e outro motivo para usar métodos protegidos!). Eu prefiro uma classe que faz uso de membros virtuais protegidos:
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
Em nossa nova classe, toda inicialização ainda é delegada à classe derivada. Desde que seja lançada uma exceção, mantemos o contrato "esta classe é inicializada" que, segundo nosso método, acontecerá.