Что такое интерфейсы в C++?

Ответ

В C++ интерфейс — это абстрактный класс, все методы которого являются чисто виртуальными. Он определяет контракт (набор методов), который обязаны реализовать производные классы. Это ключевой механизм для достижения полиморфизма и разделения интерфейса и реализации.

Пример интерфейса и его реализации:

// Интерфейс (абстрактный класс с чисто виртуальными методами)
class IDrawable {
public:
    virtual void Draw() const = 0; // Чисто виртуальный метод
    virtual ~IDrawable() = default; // Виртуальный деструктор обязателен
};

// Конкретный класс, реализующий интерфейс
class Circle : public IDrawable {
public:
    void Draw() const override {
        std::cout << "Drawing a circle." << std::endl;
    }
};

// Использование через указатель на базовый класс (интерфейс)
void renderShape(const IDrawable& shape) {
    shape.Draw(); // Полиморфный вызов
}

int main() {
    Circle c;
    renderShape(c); // Output: Drawing a circle.
    return 0;
}

Ключевые особенности:

  • Создать экземпляр абстрактного класса (интерфейса) нельзя.
  • Производный класс должен переопределить все чисто виртуальные методы, иначе он тоже станет абстрактным.
  • Виртуальный деструктор в базовом классе гарантирует корректное разрушение объектов производных классов через указатель на базовый.

Ответ 18+ 🔞

А, ну это ж классика, ебать мои старые костыли! Си-плюс-плюс и его интерфейсы. Слушай, тут всё просто, как три копейки, но если не въехать — потом овердохуища проблем.

Представь, что интерфейс — это такой устный договор, контракт, понимаешь? Ты типа говоришь: «Слушай, чувак, вот есть класс IDrawable. Чтобы называться моим наследником и чтобы я тебя вообще в гроссбух принял, ты обязан уметь метод Draw() выполнять. А как ты его сделаешь — твои проблемы, хоть на ушах стой, но чтоб был!». Это и есть абстрактный класс, где все методы — чисто виртуальные. То есть, они объявлены, но нихуя не реализованы, просто заглушки с = 0.

Вот смотри, как это выглядит в коде, тут всё честно:

// Это наш ультиматум, наш контракт. Интерфейс.
class IDrawable {
public:
    virtual void Draw() const = 0; // Видишь `= 0`? Это и есть чисто виртуальный метод. Требование!
    virtual ~IDrawable() = default; // А это, ёпта, святое! Виртуальный деструктор. Без него потом, при удалении, будет тебе хиросима и нигасраки — утечки памяти, неопределённое поведение, пиздец полный.
};

// А вот прилежный ученик, который контракт выполняет.
class Circle : public IDrawable {
public:
    void Draw() const override { // Ключевое слово `override` — это типа «я, блядь, точно переопределяю тот метод, который ты просил, а не свою херню выдумываю».
        std::cout << "Drawing a circle." << std::endl;
    }
};

// Магия полиморфизма. Функции похуй, какой конкретно объект ей скормили.
void renderShape(const IDrawable& shape) {
    shape.Draw(); // Она знает только одно: у тебя есть метод Draw(). И вызывает его. А рисуется круг, квадрат или хуй в пальто — ей не важно.
}

int main() {
    Circle c;
    renderShape(c); // Сработает! Output: Drawing a circle.
    return 0;
}

Важные моменты, которые в голове держать надо, а то будет манда с ушами:

  1. Создать объект интерфейса (IDrawable) — нихуя нельзя. Это как пытаться упаковать в коробку одну только инструкцию «собери стул». Абстракция, ёпта. Компилятор тебе сразу: «Sam от себя охуел? Абстрактный класс, иди нахуй».
  2. Наследник обязан переопределить все эти чисто виртуальные методы. Если хоть один забудешь — сам станешь абстрактным, и тебя тоже инстанциировать будет нельзя. Распиздяйство не прокатывает.
  3. Виртуальный деструктор в базе — это закон. Представь, что у тебя указатель IDrawable* ptr = new Circle();. Потом делаешь delete ptr;. Если деструктор не виртуальный, вызовется деструктор только для IDrawable, а для Circle — нихуя. Память от Circle не освободится, ресурсы не почистятся. Это пизда рулю. Поэтому всегда делай его виртуальным. Хоть пустой, но виртуальный.

Вот и вся философия. Разделил, что надо делать (интерфейс), от того, как это делать (реализация). И живи спокойно, подменяй объекты, расширяй систему — красота, а не жизнь. Главное — договорённости не нарушай.