0Pricing
C++ Academy · Урок

Абстрактные классы и чисто виртуальные методы

Определяйте интерфейсы с помощью чисто виртуальных методов и обеспечивайте выполнение контрактов производных классов.

«Абстрактные классы и чисто виртуальные методы» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Одиночное и множественное наследование
  2. Виртуальные функции и таблица vtable
  3. Абстрактные классы и чисто виртуальные методы
  4. Наследование и композиция: компромиссы
← Назад к C++ Academy