Передача параметров в функции C++: по значению, ссылке и const-ссылке

Передача параметров в функции C++: по значению, ссылке и const-ссылке

Передача параметров в функции C++: по значению, ссылке и const-ссылке

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

1. Передача по значению

При передаче по значению функция получает копию аргумента. Изменения внутри функции не влияют на исходную переменную.

#include <iostream>

void addTen(int x) {
    x += 10;
    std::cout << "Внутри функции: " << x << 'n';
}

int main() {
    int number = 5;

    addTen(number);

    std::cout << "После вызова: " << number << 'n';
}

Результат:

Внутри функции: 15
После вызова: 5

Переменная number не изменилась, потому что функция работала с копией.

Когда использовать передачу по значению

  • Для маленьких типов: int, double, char, bool.
  • Когда функция не должна менять исходное значение.
  • Когда копирование дешёвое и не влияет на производительность.
  • Для простых чисел передача по значению обычно является лучшим и самым понятным вариантом.

    2. Передача по ссылке

    Ссылка позволяет функции работать с исходной переменной, а не с копией. Если функция изменит параметр, изменится и объект снаружи.

    #include <iostream>
    
    void addTen(int& x) {
        x += 10;
    }
    
    int main() {
        int number = 5;
    
        addTen(number);
    
        std::cout << number << 'n'; // 15
    }
    

    Здесь int& x означает: параметр x — это ссылка на исходную переменную. Поэтому изменение x меняет number.

    Когда использовать передачу по ссылке

  • Когда функция должна изменить переданный объект.
  • Когда нужно вернуть несколько результатов через параметры.
  • Когда объект большой, и копирование нежелательно, но функция действительно должна его менять.
  • Пример обмена значений:

    #include <iostream>
    
    void swapValues(int& a, int& b) {
        int temp = a;
        a = b;
        b = temp;
    }
    
    int main() {
        int x = 10;
        int y = 20;
    
        swapValues(x, y);
    
        std::cout << x << ' ' << y << 'n'; // 20 10
    }
    

    В реальном C++ для обмена обычно используют std::swap, но такой пример хорошо показывает смысл ссылок.

    3. Передача по const-ссылке

    const-ссылка — один из самых полезных приёмов в C++. Она позволяет не копировать объект, но при этом запрещает изменять его внутри функции.

    #include <iostream>
    #include <string>
    
    void printName(const std::string& name) {
        std::cout << "Имя: " << name << 'n';
    
        // name += "!"; // Ошибка: менять const-параметр нельзя
    }
    
    int main() {
        std::string userName = "Анна";
        printName(userName);
    }
    

    Если бы мы написали void printName(std::string name), строка копировалась бы при каждом вызове. Для маленькой строки это незаметно, но для больших объектов или частых вызовов лишнее копирование может стать проблемой.

    Когда использовать const-ссылку

  • Для строк, контейнеров и пользовательских классов, если функция только читает данные.
  • Когда копирование объекта может быть дорогим.
  • Когда вы хотите явно показать: функция не изменит аргумент.
  • Например, так удобно выводить данные о пользователе:

    #include <iostream>
    #include <string>
    
    struct User {
        std::string name;
        int age;
    };
    
    void printUser(const User& user) {
        std::cout << user.name << ", " << user.age << " летn";
    }
    
    int main() {
        User user{"Иван", 25};
        printUser(user);
    }
    

    Сравнение способов передачи параметров

    СпособКопированиеМожно изменить оригиналКогда применять
    По значениюДаНетМаленькие типы, независимая копия
    По ссылкеНетДаНужно изменить объект
    По const-ссылкеНетНетБольшие объекты только для чтения

    Типичная ошибка новичков

    Новички часто передают большие объекты по значению, хотя функция только читает данные:

    void printItems(std::vector<std::string> items) {
        // items копируется целиком — это может быть дорого
    }
    

    Лучше так:

    void printItems(const std::vector<std::string>& items) {
        // копирования нет, изменить items нельзя
    }
    

    Для этого примера нужен заголовок <vector>, но суть проста: если контейнер не меняется, передавайте его по const&.

    Практические рекомендации

  • int, double, bool, char обычно передавайте по значению.
  • std::string, std::vector, std::map и свои классы чаще передавайте по const&, если функция только читает.
  • Используйте обычную ссылку &, только если функция действительно должна изменить аргумент.
  • Не делайте параметры изменяемыми «на всякий случай» — это ухудшает читаемость и повышает риск ошибок.
  • Если функция возвращает один результат, чаще лучше использовать return, а не изменяемый параметр.
  • Мини-практика

    Попробуйте определить, какой способ передачи подходит для каждой функции:

    double square(double x);                 // по значению
    void normalize(std::string& text);       // по ссылке, если меняем строку
    void printReport(const Report& report);  // по const-ссылке, если только читаем
    

    Если вы хотите не просто выучить отдельные правила, а собрать цельную картину языка — функции, ссылки, классы, память, STL и практические задачи — посмотрите курс «Программирование на C++ с Нуля до Гуру». Он хорошо подходит тем, кто хочет уверенно перейти от основ к реальной разработке на C++.

    Вывод

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

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий