• Зачем нужен амперсанд перед именем функции/метода?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    На самом деле понятнее писать вот так:
    int& Foo();

    Функция возвращает ссылку на int. Ссылка - это как указатель, только она не может указывать вникуда. Соответственно, вы не можете завести переменную ссылку сразу не инициализировав ее - а на что она будет указывать. И также ссылки, в отличии от указателей, не надо ее разыменовывать.

    Использовать можно, например, вот так:
    int& ref = Foo();
    std::cout << ref+10;


    Тут под переменную ref не выделяется память, ведь это ссылка, которая инициализируется тем, что вернула Foo. Так же сам объект не копируется. Максимум, под капотом скопируется адрес.
    Поэтому ссылки имеет смысл заводить на тяжелые объекты, чтобы не копировать их зря и не выделять память.

    Так же можно через эту возвращенную ссылку изменять основной объект:
    int x;
    int& Foo() {
        return x;
    }
    ...
    
    x = 0;
    int& ref = Foo();
    ref = 10;
    std::cout << x:

    Этот код выведет 10.

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

    Ну и еще, можно с этой возвращенной ссылкой работать и как с обычным int:
    int x = 2 + Foo();
    Но если вы не собираетесь менять значение внутри или не пытаетесь сэкономить на копировании объекта, то вам нет смысла вообще ссылки использовать.

    Ну и, конечно, аккуратно со ссылками надо быть. Вполне можно извернуться и получить ссылку указывающую на удаленную память. Напрямую ссылки на локальные переменные компилятор возвращать не дает, но если сначала взять адрес в указатель, а потом его разименовать и вернуть как ссылку, то вы получите undefined behavior.
    Ответ написан
    1 комментарий
  • Что означает *&?

    Nipheris
    @Nipheris Куратор тега C++
    делает тоже самое что и передача простого int по ссылке в функцию?

    Скорее всего вы не очень удачно выразились, поэтому попробую догадаться: да, передача ссылки на int, ссылки на float, ссылки на int* и ссылки на float** ничем принципиально не отличается. В обоих случаях вы получаете идентификатор, в кторый можно присваивать значение того типа, на которое у вас ссылка (т.е. int, float, указатель на int, указатель на указатель на float), и это значение попадёт в ту область памяти, которая была "завёрнута" в ссылку при вызове функции. Это может быть как обычная переменная, так и какой-нибудь разыменованный указатель.
    Ответ написан
    Комментировать