Полиморфизм в С++
Слово полиморфизм означает наличие множества форм. Как правило, полиморфизм возникает, когда существует иерархия классов и они связаны наследованием.
Полиморфизм 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++