PLLUG C++/Qt Roadmap Book
  • Вступ
  • Найважливіший розділ у цій книжці
    • Кілька критично важливих порад
    • Встановлення середовища та початок роботи
    • Підготовка до роботи. Командний рядок.
      • Встановлення та налаштування суперконсолі (тільки на Windows)
      • Cheatsheet: Робота з командним рядком
    • Компіляція та запуск першої програми
      • Найменьша програма мовою С++
      • Компіляція програми: як це працює
      • Починаємо програмувати
    • Базова робота з Git та створення власного репозиторію
      • Підготовка до роботи
      • Створюємо репозиторій та заливаємо на GitHub
      • Cheatsheet: Простий алгоритм для роботи з системою контролю версій (одна гілка, один розробник)
      • Працюємо з Git правильно
  • Мова С++ - швидкий вступ та обрані теми
    • Змінні. Деякі з основних типів та їх застосування.
      • Типи int та double
      • Тип bool
      • Тип char
      • Тип std::string
      • Тип std::vector
      • Тип std::array
    • Ключове слово const
  • Середовище розробки QtCreator
    • Налаштування та підготовка до роботи
      • Налаштування інструментаріїв
    • Довідка та ресурси
    • Гарячі клавіші
    • Робота з проектами у QtCreator
      • Файли проекту
      • Основні змінні, які беруть участь у описі проекту
      • Компіляція проекту Qt
      • Очистка проекту
  • Абстрактні типи даних та керування памяттю
    • Абстрактні типи даних
      • Об'єкти та класи. Абстракція.
      • Поля та методи класу
      • Успадкування
      • Віртуальні методи та поліморфізм
    • Вказівники та пам'ять
      • Адреса
      • Вказівники
      • Вказівники: примітивна демонстрація програми у пам'яті
      • Час зберігання об'єкту
  • Знайомство з Qt5
    • Огляд Qt5
      • Ласкаво просимо у світ Qt
      • Огляд можливостей Qt 5
      • Ліцензування Qt
      • Короткий огляд історії Qt
      • “Екосистема” Qt
    • Створення графічного інтерфейсу засобами Qt
      • Віджети (Widgets)
      • Компонування (Layouts)
      • Сигнально-слотові з'єднання
      • Створення сигналів (signals) та слотів (slots)
      • Підсумок: сигнально-слотові з'єднання
      • Коротко про елементи графічного інтерфейсу та їх використання
  • Cheatsheets
  • Demos
  • Missions
    • Mission 1: Досліджуємо Git та командний рядок
    • Mission 2: Консольна гра
    • Mission 3: MazeGame
    • Mission 4: Створюємо абстрактний тип даних
Powered by GitBook
On this page
  • Віртуальні методи
  • Абстрактні класи та чисто віртуальні методи
  • Поліморфізм
  • Корисні посилання
  1. Абстрактні типи даних та керування памяттю
  2. Абстрактні типи даних

Віртуальні методи та поліморфізм

Віртуальні методи

Розглянемо клас Shape з методом name() оголошений та визначений наступним чином:

class Shape
{
public:
    virtual std::string name() const;
};

std::string Shape::name() const
{
    return "Shape";
}

У цьому випадку, метод Shape::name() оголошено з ключовим словом virtual. Метод Shape::name() є віртуальним методом. Зверніть увагу, що ключове слово virtual використовують тільки при оголошенні методу класу (а не при визначенні реалізації методу). Для того, щоб продемонструвати, що дає віртуальний метод, успадкуємо від нього клас Circle:

class Circle : public Shape
{
public:
    Circle(double radius)
        : mRadius{radius} {}

    virtual std::string name() const override
    {
        return "Circle";
    }

private:
    double mRadius;
};

Зверніть увагу: метод Circle::name() - віртуальний та перевизначений у класі Circle. Це означає, що коли ми створимо об'єкти відповідних класів, та викличемо метод name() - те, який з методів name() буде викликано (класу-батька чи класу-нащадка) буде визначено в процесі роботи програми в залежності від того, об'єкт якого класу це є.

Для того щоб пояснити сказане вище розглянемо приклад:

int main()
{  
  Circle c1{10.0};
  Shape &circleRef = c1;
  std::cout << circleRef.name() << std::endl;

  Shape s1;
  Shape &shapeRef = s1;
  std::cout << shapeRef.name() << std::endl;
}

Якщо запустити цю програму, то ми побачимо наспупний вивід:

Circle
Shape

Тобто незважаючи на те, що circleRef це посилання на Shape, у процесі роботи програми було викликано саме метод Circle::name(), а не Shape::name().

Якщо би метод Shape::name() не був би віртуальним, то при виклику shapeRef.name() викликався би метод Shape::name() і ми би отримали вивід:

Shape
Shape

Таким чином: Виклик віртуального методу визначається динамічно в залежності від класу об'єкту. Клас який містить віртуальні методи називають поліморфним класом.

Навіщо нам потрібні віртуальні методи ми побачимо в кінці цього розділу. А зараз підсумуємо те, як можна створити віртуальний метод:

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

#include <math.h> // Include header for doing math

class Shape
{
public:
    virtual std::string name() const
    {
        return "Shape";
    }

    virtual double area() const = 0; // Pure virtual method
};
double Rectangle::area() const
{
    return mWidth * mHeight;
}

double Circle::area() const
{
    return M_PI * mRadius * mRadius;
}

Поліморфізм

void printArea(const Shape& shape)
{
    std::cout << "Area of " << shape.name()
        << " is " << shape.area() << std::endl;
}
int main()
{
    Circle circle{3.0};
    Rectangle rect{5.0, 6.0};

    // Функція printArea  може працювати як з об'єктом Circle так і з об'єктом Rectangle
    printArea(circle);
    printArea(rect);
}

Корисні посилання

PreviousУспадкуванняNextВказівники та пам'ять

Last updated 7 years ago

http://isblog.com.ua/2012-12_virtual_functions_in_cpp