Полиморфизм в С++
Слово полиморфизм означает наличие множества форм. Как правило, полиморфизм возникает, когда существует иерархия классов и они связаны наследованием.
Полиморфизм C++ означает, что вызов функции-члена приведет к выполнению другой функции в зависимости от типа объекта, который вызывает функцию.
Рассмотрим следующий пример, в котором базовый класс был получен двумя другими классами —
Живая демонстрация#include <iostream> using namespace std; class Shape { protected: int width, height; public: Shape( int a = 0, int b = 0){ width = a; height = b; } int area() { cout << "Parent class area :" <<endl; return 0; } }; class Rectangle: public Shape { public: Rectangle( int a = 0, int b = 0):Shape(a, b) { } int area () { cout << "Rectangle class area :" <<endl; return (width * height); } }; class Triangle: public Shape { public: Triangle( int a = 0, int b = 0):Shape(a, b) { } int area () { cout << "Triangle class area :" <<endl; return (width * height / 2); } }; // Main function for the program int main() { Shape *shape; Rectangle rec(10,7); Triangle tri(10,5); // store the address of Rectangle shape = &rec; // call rectangle area. shape->area(); // store the address of Triangle shape = &tri; // call triangle area. shape->area(); return 0; }
Когда приведенный выше код скомпилирован и выполнен, он дает следующий результат —
Parent class area : Parent class area :
Причина неправильного вывода в том, что вызов функции area() устанавливается компилятором один раз как версия, определенная в базовом классе. Это называется статическим разрешением. вызова функции или статической компоновки - фиксируется вызов функции до выполнения программы. Это также иногда называют ранним связыванием. потому что функция area() устанавливается во время компиляции программы.
Но теперь давайте внесем небольшие изменения в нашу программу и поставим перед объявлением area() в классе Shape ключевое слово virtual. чтобы это выглядело так -
class Shape { protected: int width, height; public: Shape( int a = 0, int b = 0) { width = a; height = b; } virtual int area() { cout << "Parent class area :" <<endl; return 0; } };
После этой небольшой модификации, когда код предыдущего примера скомпилирован и выполнен, он дает следующий результат —
Rectangle class area Triangle class area
На этот раз компилятор смотрит на содержимое указателя, а не на его тип. Следовательно, поскольку адреса объектов классов tri и rec хранятся в *shape, вызывается соответствующая функция area().
Как видите, каждый из дочерних классов имеет отдельную реализацию функции area(). Вот как полиморфизм обычно используется. У вас есть разные классы с функцией с одним и тем же именем и даже с одинаковыми параметрами, но с разными реализациями.
Виртуальная функция
виртуальный function – это функция базового класса, объявленная с использованием ключевого слова virtual. . Определение виртуальной функции в базовом классе с другой версией в производном классе сигнализирует компилятору, что нам не нужна статическая компоновка для этой функции.
Чего мы действительно хотим, так это выбора функции, которая будет вызываться в любой заданной точке программы, на основе типа объекта, для которого она вызывается. Такого рода операции называются динамическими связями. или поздняя привязка .
Чисто виртуальные функции
Возможно, вы хотите включить виртуальную функцию в базовый класс, чтобы ее можно было переопределить в производном классе для соответствия объектам этого класса, но нет осмысленного определения, которое вы могли бы дать для функции в базовом классе. .
Мы можем изменить область виртуальной функции () в базовом классе на следующую —
class Shape { protected: int width, height; public: Shape(int a = 0, int b = 0) { width = a; height = b; } // pure virtual function virtual int area() = 0; };
=0 сообщает компилятору, что у функции нет тела, и виртуальная функция выше будет называться чистой виртуальной функцией. .
Язык C
- Операторы С++
- Передача массива в функцию в программировании на C++
- Классы и объекты С++
- Дружественные функции C++ и дружественные классы
- Шаблоны классов С++
- Перегрузка оператора C++ с примерами
- Классы хранения в C++
- Перегрузка C++ (оператор и функция)
- Абстракция данных в C++
- Инкапсуляция данных в C++