


В чем разница между перегрузкой функций и переопределением виртуальных функций в контексте полиморфизма? C++
Перегрузка функций и переопределение виртуальных функций — это два понятия объектно-ориентированного программирования, которые широко используются в C++. Хотя оба они кажутся похожими, поскольку связаны с использованием одного и того же имени функции, между ними есть ключевые различия.
Перегрузка функций (Function Overloading)
Перегрузка функций — это процесс создания нескольких функций с одинаковым именем, но с различными параметрами (или сигнатурой). Перегрузка функций служит для выполнения похожей, но технически различной задачи, в зависимости от аргументов функции. Компилятор определяет, какая функция должна быть вызвана, исходя из предоставленных при вызове аргументов.
void display(int i) {
std::cout << "Displaying integer: " << i << std::endl;
}
void display(std::string s) {
std::cout << "Displaying string: " << s << std::endl;
}
// Вышеуказанные функции перегружены и компилятор знает, какую из них вызвать в зависимости от переданных аргументов.
Переопределение функций (Function Overriding)
Переопределение функций происходит, когда подкласс или производный класс предоставляет специализированную реализацию функции, которая уже определена в его базовом классе или родительском классе. Это ключевая часть полиморфизма в объектно-ориентированном программировании. Переопределенная функция обычно виртуальна в базовом классе и используется для изменения или расширения поведения базового класса.
class Base {
public:
virtual void print() {
std::cout << "Print of Base" << std::endl;
}
};
class Derived : public Base {
public:
void print() override { // Функция переопределена.
std::cout << "Print of Derived" << std::endl;
}
};
// Класс Derived переопределяет функцию print() базового класса Base.
Основные различия:
Назначение: Перегрузка функций используется для создания функций с тем же именем, но работающих с различными типами данных или разным числом параметров; переопределение функций используется для изменения поведения функции в производном классе.
Полиморфизм: Перегрузка функций не связана с полиморфизмом (это статический или компиляционный полиморфизм), в то время как переопределение функций является формой динамического полиморфизма, позволяющего объектам вести себя по-разному в зависимости от их типа во время выполнения программы.
Сигнатура функции: Перегруженные функции имеют одинаковые имена, но разные сигнатуры; переопределенные функции имеют ту же сигнатуру, что и оригинальная функция в базовом классе.
Ключевое слово virtual: В переопределении функций часто задействованы виртуальные функции, позволяющие производному классу предоставлять собственную реализацию функции; перегрузка функций не требует использования виртуальных функций.
Если кратко, то перегрузка функций - это когда две функции с одинаковым именем имеют различные параметры или сигнатуру.
А компилятор определяет, какую вызвать в зависимости от контекста.
#include <iostream>
using namespace std;
int sum(int a, int b) {return a + b;}
double sum(double a, double b) {return a + b;}
int main() {
cout<<sum(6, 7)<<endl;
cout<<sum(6.8, 7.9);
return 0;
}
/*
13
14.7
*/
Переопределение виртуальных функций - это когда функция, собственно, переопределяется:
#include <iostream>
using namespace std;
class Base {
public:
virtual void print() {puts("Hello, World!");}
};
class Derived: public Base {
public:
void print() override {puts("Hello, Base!");}
};
int main() {
Base a;
Derived b;
a.print();
b.print();
return 0;
}
/*
Hello, World!
Hello, Base!
*/