Абстрактные классы и чисто виртуальные методы
Определяйте интерфейсы с помощью чисто виртуальных методов и обеспечивайте выполнение контрактов производных классов.
«Абстрактные классы и чисто виртуальные методы» — бесплатный урок C++ Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Что такое абстрактный класс
Абстрактный класс имеет хотя бы одну чисто виртуальную функцию, объявленную с помощью = 0. Нельзя напрямую создать его экземпляр.
class Animal {
public:
virtual void speak() const = 0; // pure virtual
virtual ~Animal() = default;
};
// Animal a; // ERROR: cannot instantiateЧисто виртуальные функции
= 0 указывает, что у функции нет реализации по умолчанию. Производные классы должны переопределить её, прежде чем класс можно будет инстанцировать.
Реализация интерфейса
Производные классы предоставляют конкретные тела для всех чисто виртуальных функций.
class Dog : public Animal {
public:
void speak() const override {
std::cout << "Woof!\n";
}
};
Dog d;
d.speak(); // Woof!Абстрактные классы как интерфейсы
Абстрактный класс, содержащий только чисто виртуальные методы (и не содержащий данных), играет роль интерфейса, как в других языках.
class Drawable {
public:
virtual void draw() const = 0;
virtual ~Drawable() = default;
};Объединение реализации и интерфейса
Абстрактные классы могут содержать как чисто виртуальные методы, так и конкретные методы. Чисто виртуальные функции определяют контракт, а конкретные методы предоставляют общее поведение.
class Logger {
public:
void logInfo(const std::string& msg) { log("INFO", msg); }
void logError(const std::string& msg) { log("ERROR", msg); }
protected:
virtual void log(const std::string& level, const std::string& msg) = 0;
};Чисто виртуальная функция с реализацией по умолчанию
У чисто виртуальной функции может быть тело — это полезно как реализация по умолчанию, которую могут вызывать производные классы.
class Base {
public:
virtual void f() = 0;
};
void Base::f() {
std::cout << "default behavior\n";
}
class Derived : public Base {
public:
void f() override {
Base::f(); // call the default
std::cout << "extra\n";
}
};Использование через указатели и ссылки
Полиморфный код хранит абстрактные объекты через указатели или ссылки на базовый тип.
void perform(const Animal& a) {
a.speak();
}Хранение в контейнерах
Векторы не могут хранить абстрактные типы по значению. Используйте указатели, обычно интеллектуальные.
std::vector<std::unique_ptr<Animal>> zoo;
zoo.push_back(std::make_unique<Dog>());
zoo.push_back(std::make_unique<Cat>());
for (auto& a : zoo) a->speak();Когда использовать абстрактные классы
Используйте их, когда:
- Вы хотите определить общий интерфейс для нескольких несвязанных реализаций
- Вам нужен базовый тип для полиморфных контейнеров
- Вы хотите внедрять поведение через производные классы (паттерн «шаблонный метод»)
Альтернативы: концепции и шаблоны
Для полиморфизма времени компиляции концепции и шаблоны C++20 часто заменяют абстрактные классы, не добавляя затрат во время выполнения. Используйте виртуальные функции, когда полиморфизм нужен во время выполнения.
Проблема: срезка
Передавайте абстрактные классы по ссылке или через указатель. Передача по значению всё равно невозможна (нельзя создать экземпляр абстрактного типа), но передача производных классов по значению приводит к срезке.
Быстрая проверка
Что делает класс абстрактным в C++?
Итоги
Абстрактные классы — классы хотя бы с одним чисто виртуальным методом — определяют интерфейсы для полиморфного кода. Используйте их с указателями или ссылками (часто интеллектуальными указателями), чтобы выбирать поведение во время выполнения.
Часто задаваемые вопросы
Урок «Абстрактные классы и чисто виртуальные методы» бесплатный?
Да — полный текст урока «Абстрактные классы и чисто виртуальные методы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Абстрактные классы и чисто виртуальные методы»?
Определяйте интерфейсы с помощью чисто виртуальных методов и обеспечивайте выполнение контрактов производных классов. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Абстрактные классы и чисто виртуальные методы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Одиночное и множественное наследование
- Виртуальные функции и таблица vtable
- Абстрактные классы и чисто виртуальные методы
- Наследование и композиция: компромиссы