Top.Mail.Ru
Ответы
Аватар пользователя
Аватар пользователя
Аватар пользователя
Аватар пользователя
Программирование
+2

В чем разница между перегрузкой функций и переопределением виртуальных функций в контексте полиморфизма? C++

По дате
По рейтингу
Аватар пользователя
Новичок

Перегрузка функций и переопределение виртуальных функций — это два понятия объектно-ориентированного программирования, которые широко используются в C++. Хотя оба они кажутся похожими, поскольку связаны с использованием одного и того же имени функции, между ними есть ключевые различия.

Перегрузка функций (Function Overloading)
Перегрузка функций — это процесс создания нескольких функций с одинаковым именем, но с различными параметрами (или сигнатурой). Перегрузка функций служит для выполнения похожей, но технически различной задачи, в зависимости от аргументов функции. Компилятор определяет, какая функция должна быть вызвана, исходя из предоставленных при вызове аргументов.

12345678910
 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)
Переопределение функций происходит, когда подкласс или производный класс предоставляет специализированную реализацию функции, которая уже определена в его базовом классе или родительском классе. Это ключевая часть полиморфизма в объектно-ориентированном программировании. Переопределенная функция обычно виртуальна в базовом классе и используется для изменения или расширения поведения базового класса.

12345678910111213141516
 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: В переопределении функций часто задействованы виртуальные функции, позволяющие производному классу предоставлять собственную реализацию функции; перегрузка функций не требует использования виртуальных функций.

Аватар пользователя
Мастер

Если кратко, то перегрузка функций - это когда две функции с одинаковым именем имеют различные параметры или сигнатуру.
А компилятор определяет, какую вызвать в зависимости от контекста.

12345678910111213
 #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
*/ 


Переопределение виртуальных функций - это когда функция, собственно, переопределяется:

123456789101112131415161718192021
 #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! 
*/