Просто приклад, який я використовував у минулому. Захищені методи чудово підходять для забезпечення функцій, що залежать від впровадження, а також дозволяють базовому класу правильно відстежувати речі. Розглянемо базовий клас, який забезпечує функцію ініціалізації, що перезаписується, але також повинен мати стан для визначення, чи ініціалізовано:
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
Тут все добре і добре. За винятком випадків, коли похідний клас не намагається називати setInitialized()
не в останню чергу тим, що хтось може його викликати (ми могли б зробити це захищеним тут, і ще одна причина використовувати захищені методи!). Я дуже віддаю перевагу класу, який використовує віртуальних захищених членів:
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
У нашому новому класі вся ініціалізація все ще делегована похідному класу. За умови виключення виключення, ми підтримуємо контракт "цей клас ініціалізований", який, за нашим методом, каже, відбудеться.