Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции C++.doc
Скачиваний:
0
Добавлен:
06.02.2020
Размер:
1.44 Mб
Скачать

4.9.3 Возврат ссылок

Функция может возвращать ссылку. В результате такая функция может использоваться в левой части оператора присваивания! В качестве примера рассмотрим следующую простую программу:

#include <iostream.h>

char& replace(int i, char *s) // возврат ссылки

{

return s[i];

}

char s[80] = "Hello There";

int main ()

{

replace(5) = 'X'; // присвоение Х пробелу после Hello

cout << s;

return 0;

}

Эта программа заменяет пробел между словами “Hello” и “There” символом ‘Х’. В результате программа выводит на экран «HelloXThere».

Функция replace() в соответствии со своим объявлением возвращает ссылку на символ. В соответствии со своей реализацией функция replace() возвращает ссылку на элемент масси­ва s, определяющийся индексом i. Далее возвращаемая функцией replace() ссылка используется функцией main() для присвоения элементу буквы «X».

4.9.4 Независимые ссылки

Хотя в первую очередь ссылки включены в C++ для поддержки передачи параметров по ссылке и возвращения результата функции по ссылке, можно объявлять переменные ссылочного типа и как самостоятельные переменные. В таком случае они называются независимыми ссылками (independent references). Однако в таком случае их возможности серьезно ограничиваются.

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

#include <iostream.h>

int main()

{

int j, k;

int &i = j; // независимая ссылка на j

j = 10;

cout << j << " " << i; // выводит 10 10

k = 121;

i = k; // копирование значения, а не адреса к в j

cout << "\n" << j; // выводит 121

return 0;

}

Программа выдаст следующие данные:

10 10

121

Адрес, на который указывает ссылочная переменная i, фиксирован и не может меняться. Так при выполнении присвоения i = k величина к копируется в j.

Вот другой пример. Инструкция i++ не вызывает изменения адреса. Вместо этого значение переменной k увеличивается на 1. (Надо помнить, что ссылки не являются указателями.)

Ссылочные переменные могут указывать на константы:

const int &i = 100;

4.9.5 Использование ссылок для перегрузки унарных операторов

Используя знания относительно ссылочных переменных, теперь можно легко понять, как унар­ные операторы перегружаются с помощью дружественных функций. Для начала вернемся к ис­ходной версии оператора ++ по отношению к классу point. Для удобства он представлен ниже:

point point::operator++()

{

х++; У++; z++;

return *this;

}

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

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

class point

{

int x, y, z; // трехмерные координаты

public:

friend point operator+(point p1, point p2);

point operator=(point p2); // p1 подразумевается

friend point operator++(point &p1);

void show();

void set(int mx, int my, int mz);

};

point operator++(point &p1)

{

p1.x++; p1.y++; p1.z++;

return p1;

}

ПАМЯТКА: Для перегрузки операторов следует пользоваться функциями-члена­ми. Функции-друзья предназначаются в C++ большей частью для специальных си­туаций.