Вы добавляете логирование в базовый класс, а оно не срабатывает? Добро пожаловать в мир публичных виртуальных функций.
Проблема: Когда виртуальная функция публична, производные классы могут обойти любую логику базового класса:
// ❌ Классический антипаттерн
class Base {
public:
virtual void process(Data& data) {
log("Processing...");
// Логика
}
};
class Derived : public Base {
public:
void process(Data& data) override {
// Производный класс забыл вызвать Base::process()
// Логирование пропало!
}
};
💡Паттерн NVI решает это:
NVI (Non-Virtual Interface) — паттерн, где публичные методы невиртуальные, а виртуальные — приватные. Базовый класс становится "шлюзом", контролирующим доступ к кастомизируемой логике.class IProcessor {
public:
void process(Data& data) { // Невиртуальный public
validate(data); // Общая логика
logStart(); // Тоже общая
process(data); // Кастомизация
logEnd();
}
private:
virtual void process(Data& data) = 0; // Виртуальный private
void validate(Data& data) { /* ... */ }
void logStart() { /* ... */ }
void logEnd() { /* ... */ }
};Теперь каждый вызов
process() гарантированно проходит через логирование. Производные классы физически не могут его обойти.🔹Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹Сайт Proglib
Библиотека C/C++ разработчика
#константная_правильность