Что такое полиморфизм в C ++?
В C ++ полиморфизм заставляет функцию-член вести себя по-разному в зависимости от объекта, который ее вызывает / вызывает. Полиморфизм - это греческое слово, которое означает иметь много форм. Это происходит, когда у вас есть иерархия классов, связанных наследованием.
Например, предположим, что у нас есть функция makeSound (). Когда кошка вызывает эту функцию, она издает звук мяуканья. Когда корова вызывает ту же функцию, она издает звук мычания.
Хотя у нас есть одна функция, в разных обстоятельствах она ведет себя по-разному. Функция имеет множество форм; следовательно, мы достигли полиморфизма.
В этом руководстве по C ++ вы узнаете:
- Что такое полиморфизм?
- Типы полиморфизма
- Полиморфизм времени компиляции
- Перегрузка функций
- Перегрузка оператора
- Полиморфизм времени выполнения
- Переопределение функции
- Виртуальная функция C ++
- Полиморфизм времени компиляции против. Полиморфизм времени выполнения
Типы полиморфизма
C ++ поддерживает два типа полиморфизма:
- Полиморфизм времени компиляции и
- Полиморфизм времени выполнения.
Полиморфизм времени компиляции
Вы вызываете перегруженные функции, сопоставляя количество и тип аргументов. Информация присутствует во время компиляции. Это означает, что компилятор C ++ выберет правильную функцию во время компиляции.
Полиморфизм во время компиляции достигается за счет перегрузки функций и операторов.
Перегрузка функций
Перегрузка функций возникает, когда у нас есть много функций с похожими именами, но разными аргументами. Аргументы могут различаться по количеству или типу.
Пример 1:
#includeusing namespace std;void test(int i) {cout << " The int is " << i << endl;}void test(double f) {cout << " The float is " << f << endl;}void test(char const *ch) {cout << " The char* is " << ch << endl;}int main() {test(5);test(5.5);test("five");return 0;}
Выход:
Вот скриншот кода:
Пояснение к коду:
- Включите файл заголовка iostream в наш код. Мы сможем использовать его функции.
- Включите пространство имен std в наш код. Мы сможем использовать его классы, не вызывая его.
- Создайте функцию с именем test, которая принимает целочисленный параметр i. {Отмечает начало тела функционального теста.
- Оператор, который будет выполнен, если вызывается / вызывается вышеуказанный функциональный тест.
- Конец основной части приведенного выше функционального теста.
- Создайте функцию с именем test, которая принимает параметр с плавающей запятой f. {Отмечает начало тела функционального теста.
- Оператор, который будет выполнен, если вызывается / вызывается вышеуказанный функциональный тест.
- Конец тела вышеуказанного функционального теста.
- Создайте функцию с именем test, которая принимает символьный параметр ch. {Отмечает начало тела функционального теста.
- Оператор, который будет выполнен, если вызывается / вызывается вышеуказанный функциональный тест.
- Конец тела вышеуказанного функционального теста.
- Вызовите функцию main (). {Отмечает начало тела функции.
- Вызвать функцию test и передать ей 5 в качестве значения аргумента. Это вызывает тестовую функцию, которая принимает целочисленный аргумент, то есть первую тестовую функцию.
- Вызвать функцию test и передать ей 5.5 в качестве значения аргумента. Это вызовет тестовую функцию, которая принимает аргумент с плавающей запятой, то есть вторую тестовую функцию.
- Вызовите функцию test и передайте ей пять в качестве значения аргумента. Это вызовет тестовую функцию, которая принимает символьный аргумент, то есть третью тестовую функцию.
- Программа должна вернуть значение, если она выполняется успешно.
- Конец тела функции main ().
У нас есть три функции с одинаковым именем, но с разными типами аргументов. Мы добились полиморфизма.
Перегрузка оператора
В разделе «Перегрузка операторов» мы определяем новое значение оператора C ++. Это также меняет способ работы оператора. Например, мы можем определить оператор + для объединения двух строк. Мы знаем его как оператор сложения для сложения числовых значений. После нашего определения, когда оно помещено между целыми числами, оно добавит их. При размещении между строками он объединяет их.
Пример 2:
#includeusing namespace std;class ComplexNum {private:int real, over;public:ComplexNum(int rl = 0, int ov = 0) {real = rl;over = ov;}ComplexNum operator + (ComplexNum const &obj) {ComplexNum result;result.real = real + obj.real;result.over = over + obj.over;return result;}void print() {cout << real << " + i" << over << endl;}};int main(){ComplexNum c1(10, 2), c2(3, 7);ComplexNum c3 = c1+c2;c3.print();}
Выход:
Вот скриншот кода:
Пояснение к коду:
- Включите файл заголовка iostream в нашу программу, чтобы использовать его функции.
- Включите пространство имен std в нашу программу, чтобы использовать его классы, не вызывая его.
- Создайте класс с именем ComplexNum. {Отмечает начало тела класса.
- Используйте модификатор частного доступа, чтобы пометить переменные как частные, то есть к ним можно получить доступ только изнутри класса.
- Определите две целочисленные переменные, вещественные и более.
- Используйте модификатор публичного доступа, чтобы пометить конструктор как общедоступный, что означает, что он будет доступен даже извне класса.
- Создайте конструктор класса и инициализируйте переменные.
- Инициализируйте значение переменной real.
- Инициализируйте значение переменной заново.
- Конец тела конструктора.
- Нам нужно переопределить значение оператора +.
- Создайте результат типа данных типа ComplexNum.
- Используйте оператор + с комплексными числами. Эта строка добавит действительную часть числа к действительной части другого числа.
- Используйте оператор + с комплексными числами. Эта линия добавит мнимую часть числа к мнимой части другого числа.
- Программа вернет значение переменной result при успешном выполнении.
- Конец определения нового значения оператора +, то есть перегрузки.
- Вызовите метод print ().
- Выведите новое комплексное число после сложения на консоль.
- Конец тела функции print ().
- Конец тела класса ComplexNum.
- Вызовите функцию main ().
- Передайте значения как реальных, так и сложных частей, которые нужно добавить. Первая часть c1 будет добавлена к первой части c2, то есть 10 + 3. Вторая часть c1 будет добавлена ко второй части c, то есть 2 + 7.
- Выполните операцию с помощью перегруженного оператора + и сохраните результат в переменной c3.
- Вывести на консоль значение переменной c3.
- Конец тела функции main ().
Полиморфизм времени выполнения
Это происходит, когда метод объекта вызывается / вызывается во время выполнения, а не во время компиляции. Полиморфизм времени выполнения достигается за счет переопределения функции. Функция, которая должна быть вызвана / вызывается, устанавливается во время выполнения.
Переопределение функции
Переопределение функции происходит, когда функции базового класса дается новое определение в производном классе. В то время мы можем сказать, что базовая функция была переопределена.
Например:
#includeusing namespace std;class Mammal {public:void eat() {cout << "Mammals eat… ";}};class Cow: public Mammal {public:void eat() {cout << "Cows eat grass… ";}};int main(void) {Cow c = Cow();c.eat();return 0;}
Выход:
Вот скриншот кода:
Пояснение к коду:
- Импортируйте файл заголовка iostream в нашу программу, чтобы использовать его функции.
- Включите пространство имен std в нашу программу, чтобы использовать его классы, не вызывая его.
- Создайте класс с именем Mammal. {Отмечает начало тела класса.
- Используйте модификатор публичного доступа, чтобы сделать функцию, которую мы собираемся создать, общедоступной. Он будет доступен извне этого класса.
- Создайте общедоступную функцию с именем eat. {Отмечает начало тела функции.
- Распечатайте оператор, добавленный к функции cout при вызове функции eat ().
- Конец тела функции eat ().
- Конец тела класса Mammal.
- Создайте класс с именем Cow, который наследует класс Mammal. Cow - это производный класс, а Mammal - базовый класс. {Отмечает начало этого класса.
- Используйте модификатор общего доступа, чтобы отметить функцию, которую мы собираемся создать, как общедоступную. Он будет доступен извне этого класса.
- Переопределите функцию eat (), которая была определена в базовом классе. {Отмечает начало тела функции.
- Оператор, выводимый на консоль при вызове этой функции.
- Конец тела функции eat ().
- Конец тела класса Cow.
- Вызовите функцию main (). {Отмечает начало тела этой функции.
- Создайте экземпляр класса Cow и присвойте ему имя c.
- Вызовите функцию eat (), определенную в классе Cow.
- Программа должна вернуть значение после успешного завершения.
- Конец функции main ().
Виртуальная функция C ++
Виртуальная функция - это еще один способ реализации полиморфизма времени выполнения в C ++. Это специальная функция, определенная в базовом классе и переопределенная в производном классе. Чтобы объявить виртуальную функцию, вы должны использовать ключевое слово virtual. Ключевое слово должно предшествовать объявлению функции в базовом классе.
Если класс виртуальной функции наследуется, виртуальный класс переопределяет виртуальную функцию в соответствии со своими потребностями. Например:
#includeusing namespace std;class ClassA {public:virtual void show() {cout << "The show() function in base class invoked… " << endl;}};class ClassB :public ClassA {public:void show() {cout << "The show() function in derived class invoked… ";}};int main() {ClassA* a;ClassB b;a = &b;a->show();}
Выход:
Вот скриншот кода:
Пояснение к коду:
- Включите файл заголовка iostream в код, чтобы использовать его функции.
- Включите пространство имен std в наш код, чтобы использовать его классы без его вызова.
- Создайте класс с именем ClassA.
- Используйте модификатор публичного доступа, чтобы пометить член класса как общедоступный.
- Создайте виртуальную функцию с именем show (). Это будет публичное мероприятие.
- Текст для печати при вызове show (). Endl - это ключевое слово C ++, которое означает конец строки. Он перемещает курсор мыши на следующую строку.
- Конец тела виртуальной функции show ().
- Конец тела класса ClassA.
- Создание нового класса с именем ClassB, который наследует класс ClassA. ClassA становится базовым классом, а ClassB становится производным классом.
- Используйте модификатор публичного доступа, чтобы пометить член класса как общедоступный.
- Переопределите виртуальную функцию show (), производную от базового класса.
- Текст для печати на консоли при вызове функции show (), определенной в производном классе.
- Конец тела функции show ().
- Конец тела производного класса ClassB.
- Вызовите функцию main (). Логика программы должна быть добавлена в ее тело.
- Создайте переменную-указатель с именем. Он указывает на класс с именем ClassA.
- Создайте экземпляр класса с именем ClassB. Экземпляру присвоено имя b.
- Назначьте значения, хранящиеся в адресе b, в переменной a.
- Вызовите функцию show (), определенную в производном классе. Реализована поздняя привязка.
- Конец тела функции main ().
Полиморфизм времени компиляции против. Полиморфизм времени выполнения
Вот основные различия между ними:
Полиморфизм времени компиляции | Полиморфизм времени выполнения |
Это также называется ранним связыванием или статическим полиморфизмом. | Это также называется поздним / динамическим связыванием или динамическим полиморфизмом. |
Метод вызывается / вызывается во время компиляции | Метод вызывается / вызывается во время выполнения |
Реализовано через перегрузку функций и перегрузку операторов. | Реализовано с помощью переопределения методов и виртуальных функций. |
Пример, перегрузка метода. Многие методы могут иметь похожие имена, но различное количество или типы аргументов. | Пример, переопределение метода. Многие методы могут иметь похожее имя и один и тот же прототип. |
Более быстрое выполнение, поскольку обнаружение методов выполняется во время компиляции | Более медленное выполнение, поскольку средство обнаружения методов выполняется во время выполнения. |
Обеспечивается меньшая гибкость для решения проблем, поскольку все известно во время компиляции. | Для решения сложных проблем предоставляется большая гибкость, поскольку методы обнаруживаются во время выполнения. |
Резюме:
- Полиморфизм означает иметь множество форм.
- Это происходит, когда существует иерархия классов, связанных наследованием.
- С полиморфизмом функция может вести себя по-разному в зависимости от объекта, который ее вызывает / вызывает.
- При полиморфизме времени компиляции вызываемая функция устанавливается во время компиляции.
- При полиморфизме времени выполнения вызываемая функция устанавливается во время выполнения.
- Полиморфизм времени компиляции определяется перегрузкой функций и операторов.
- При перегрузке функций существует множество функций с похожими именами, но разными аргументами.
- Параметры могут различаться по количеству или типу.
- В перегрузке операторов для операторов C ++ определено новое значение.
- Полиморфизм времени выполнения достигается за счет переопределения функции.
- При переопределении функции производный класс дает новое определение функции, определенной в базовом классе.