Функция может возвращать ссылку. Возвращение ссылки может оказаться полезным при перегрузке операторов определенных типов. Кроме этого, возвращение ссылки позволяет использовать функцию слева в инструкции присваивания. Это приводит к важному и неожиданному результату. Рассмотрим примеры.
Пример 1
// Простая программа с функцией, которая возвращает ссылку:
#include <iostream>
using namespace std;
int x;
int &f()
{
return x;
}
int main()
{
f() = 100; // Присваивание 100 ссылке, возвращаемой функцией f()
cout<<x<<endl;
return 0;
}
Здесь функция f() объявляется возвращающей ссылку на целое. Внутри тела функции инструкция return x; не возвращает значение глобальной переменной х, она автоматически возвращает адрес переменной х (в виде ссылки). Таким образом, внутри функции main() инструкция f() = 100; заносит значение 100 в переменную х, поскольку функция f() уже возвратила ссылку на нее.
Функция f() возвращает ссылку. Когда функция f() указана слева в инструкции присваивания, то, таким образом, слева оказывается ссылка на объект, которую возвращает эта функция. Поскольку функция f() возвращает ссылку на переменную х (в данном примере), то эта переменная х и получает значение 100.
Следует быть внимательными при возвращении ссылок, чтобы объект, на который мы ссылаемся, не вышел из области видимости. Например, изменим функцию f().
Пример 2
// Возвращение ссылки на целое
int &f()
{
int х; // х – локальная переменная
return x; // возвращение ссылки на х
}
В этом случае х становится локальной переменной функции f() и выходит из области видимости после выполнения функции. Это означает, что ссылку, возвращаемую функцией f(), уже нельзя использовать.
Возвращение функцией ссылки может быть полезно при перегрузке операторов ввода и вывода. Например:
#include <iostream>
// Объявление класса time
class time
{
// Закрытые члены класса
private:
int h, m, s;
// Общедоступные члены класса
public:
// Функция для подсчета секунд
void count_seconds()
{
cout<<"Прошло секунд: "<<h*3600+m*60+s<<endl;
}
// Конструктор по умолчанию
time()
{
h=12;
m=12;
s=12;
}
// Конструктор инициализирующий
time (int tmp)
{
cout<<"Введите расчетное время (чч[0-23], мм[0-59], сс[0-59]):"<<endl;
cin>>h;
cin>>m;
cin>>s;
}
// Дружественная функция-перегрузка оператора <<
friend ostream & operator << (ostream &os, time &t)
{
os<<"Заданное время: "<<t.h<<‘:'<<t.m<<‘:'<<t.s<<endl; return os;
}
// Дружественная функция-перегрузка оператора >>
friend istream & operator >> (istream &is, time &t)
{
cout<<"Введите час: ";
is>>t.h;
cout<<"Введите минуты: ";
is>>t.m;
cout<<"Введите секунды: ";
is>>t.s;
return is;
}
};
void main ()
{
cout<<"Создание объекта №1 с помощью конструктора без параметров:"<<endl;
time t1;
cout<<t1<<endl;
cout<<"Ввод значений для объекта №1:"<<endl;
cin>>t1;
cout<<t1<<endl;
}