Перейти к содержимому
шпаргалка.
Esc
навигацияоткрыть⌘Jпредпросмотр
На этой странице

Полиморфизм и наследование

Все темы C++ Developer

Что такое полиморфизм?

Полиморфизм в C++ — это способность функций и методов работать с объектами разных типов, объединённых общим базовым типом, через единый интерфейс. Полиморфизм позволяет создавать гибкие и расширяемые программы.

Основные виды полиморфизма:

  1. Компиляционный (статический) полиморфизм:

    • Достигается через перегрузку функций и шаблоны.

    • Пример: Перегрузка функций.

      void print(int i);
      void print(double d);
  2. Исполнительный (динамический) полиморфизм:

    • Достигается через виртуальные функции и наследование.

    • Пример: Виртуальные функции.

      class Base {
      public:
          virtual ~Base() = default;
      
          virtual void display() const {
              std::cout << "Base display" << std::endl;
          }
      };
      
      class Derived : public Base {
      public:
          void display() const override {
              std::cout << "Derived display" << std::endl;
          }
      };
      
      void show(const Base& b) {
          b.display();
      }

Пример использования:

Base* b = new Derived();
b->display();  // Вызов метода Derived через указатель на Base
delete b;

Для чего используется наследование?

Наследование в C++ используется для:

  1. Повторного использования кода: Позволяет производным классам использовать свойства и методы базового класса, уменьшая дублирование кода.

    class Base {
    public:
        void commonFunction() { /* ... */ }
    };
    
    class Derived : public Base {
        // Использует commonFunction() из Base
    };
  2. Создания иерархий классов: Организует классы в иерархию, где производные классы расширяют или уточняют поведение базового класса.

    class Animal {
    public:
        void eat() { /* ... */ }
    };
    
    class Dog : public Animal {
        void bark() { /* ... */ }
    };
  3. Полиморфизма: Позволяет обрабатывать объекты производных классов через указатели или ссылки на базовый класс, что упрощает работу с различными, но связанными типами.

    class Base {
    public:
        virtual void display() { /* ... */ }
    };
    
    class Derived : public Base {
    public:
        void display() override { /* ... */ }
    };
    
    void show(Base* b) {
        b->display();
    }

Какие бывают типы наследования?

В C++ существуют три основных типа наследования, определяющие доступ производного класса к членам базового класса:

  1. Публичное наследование (public):

    • Доступ к публичным членам базового класса остаётся публичным.

    • Доступ к защищённым членам базового класса остаётся защищённым.

    • Приватные члены базового класса остаются недоступными.

    class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
    };
    
    class Derived : public Base {
        // publicMember - public
        // protectedMember - protected
        // privateMember - недоступен
    };
  2. Защищённое наследование (protected):

    • Доступ к публичным и защищённым членам базового класса становится защищённым.

    • Приватные члены базового класса остаются недоступными.

    class Derived : protected Base {
        // publicMember - protected
        // protectedMember - protected
        // privateMember - недоступен
    };
  3. Приватное наследование (private):

    • Доступ к публичным и защищённым членам базового класса становится приватным.

    • Приватные члены базового класса остаются недоступными.

    class Derived : private Base {
        // publicMember - private
        // protectedMember - private
        // privateMember - недоступен
    };

Как запретить наследовать класс?

Чтобы запретить наследование класса в C++, можно использовать final:

Пример:
class MyClass final {
    // Тело класса
};

Класс, объявленный с final, не может быть базовым классом. Попытка унаследовать такой класс вызовет ошибку компиляции.

Также можно запретить переопределение виртуального метода с помощью final:

class Base {
public:
    virtual void someMethod() final {
        // Метод не может быть переопределён в производных классах
    }
};

class Derived : public Base {
    // void someMethod() override; // Ошибка компиляции
};

Эта страница была полезной?