Menu
Coddy logo textTech

Перегрузка функций

Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy. Урок 57 из 104.

Перегрузка функций позволяет define несколько функций с одним и тем же именем, но разными списками параметров. Компилятор выбирает подходящую версию на основе переданных вами аргументов. Это одна из ключевых форм полиморфизма времени компиляции.

Чтобы перегрузка работала, функции должны отличаться своей сигнатурой — количеством parameters, их типами или и тем, и другим:

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    int add(int a, int b, int c) {
        return a + b + c;
    }
};

Calculator calc;
calc.add(5, 3);        // Вызывает add(int, int)
calc.add(2.5, 3.7);    // Вызывает add(double, double)
calc.add(1, 2, 3);     // Вызывает add(int, int, int)

Компилятор проверяет каждый вызов и сопоставляет его с подходящим overload. Это происходит полностью во время компиляции, поэтому накладных расходов во время выполнения нет.

Важно: Один только тип return не отличает перегруженные функции. Следующее вызовет ошибку компилятора:

int getValue();
double getValue();  // Ошибка: нельзя перегружать только по типу возвращаемого значения

Перегрузка функций делает ваш код более понятным. Вместо создания отдельных имён, таких как addInts, addDoubles и addThreeInts, используйте одно содержательное имя и позвольте компилятору позаботиться обо всём остальном.

challenge icon

Задание

Легко

Давайте создадим класс форматирования сообщений, демонстрирующий возможности overload функций. Вы создадите класс Formatter с несколькими методами format(), которые обрабатывают разные типы входных данных, позволяя компилятору выбирать подходящую версию в зависимости от переданных вами аргументов.

Вы организуете код в двух файлах:

  • Formatter.h: определите класс Formatter с перегруженными методами format(), обрабатывающими разные сценарии:
    • метод, который принимает одну строку std::string и выводит: Message: <text>
    • метод, который принимает std::string и приоритет уровня int, выводя: [Priority <priority>] <text>
    • метод, который принимает std::string и временную метку double, выводя: [<timestamp>s] <text>
    • метод, который принимает три параметра std::string (sender, receiver, message) и выводит: From <sender> to <receiver>: <message>
    Все методы должны называться format(): компилятор выберет правильный из них на основе аргументов.
  • main.cpp: прочитайте четыре входных значения (каждое в отдельной строке):
    1. простой текст сообщения
    2. уровень приоритета (целое число)
    3. временная метка (число с плавающей точкой)
    4. имя отправителя

    Создайте объект Formatter и продемонстрируйте все четыре перегруженных метода:

    • вызовите format(), передав только текст сообщения
    • вызовите format(), передав текст сообщения и приоритет
    • вызовите format(), передав текст сообщения и временную метку
    • вызовите format(), передав отправителя, "Admin" в качестве получателя и текст сообщения

Например, при входных данных System ready, 3, 12.5 и Server:

Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System ready

Обратите внимание: вы вызываете одно и то же имя метода format() четыре раза, но каждый вызов обращается к отдельной версии в зависимости от типов и количества аргументов. Это полиморфизм времени компиляции в действии: компилятор определяет, какой overload использовать, ещё до запуска программы.

Попробуйте сами

#include <iostream>
#include <string>
#include "Formatter.h"

using namespace std;

int main() {
    // Считать входные данные
    string message;
    getline(cin, message);
    
    int priority;
    cin >> priority;
    
    double timestamp;
    cin >> timestamp;
    cin.ignore();
    
    string sender;
    getline(cin, sender);
    
    // TODO: Создать объект Formatter
    
    // TODO: Вызвать format() только с текстом сообщения
    
    // TODO: Вызвать format() с текстом сообщения и priority
    
    // TODO: Вызвать format() с текстом сообщения и timestamp
    
    // TODO: Вызвать format() с sender, "Admin" в качестве получателя и текстом сообщения
    
    return 0;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор C++