Четвертый BORLAND С++ и его окружение

       

Аргументы типа ссылки


Описатель ссылки может также использоваться для объявления в

функции параметров типа ссылки:

void func1 (int i);

void func2 (int &ir); // ir имеет тип "ссылка на int"

...

int sum=3;

func1(sum); // sum передается по значению

func2(sum); // sum передается по ссылке

Переданный по ссылке аргумент sum может изменяться прямо в

func2. Напротив, func1 получает только копию аргумента sum (переданного по значению), поэтому сама переменная sum функцией func1

изменяться не может.

При передаче фактического аргумента x по значению соответствующий формальный аргумент в функции принимает копию x. Любые

изменения этой копии в теле функции не отражаются на самом значении x. Разумеется, функция может возвратить значение, которое затем может использоваться для изменения x, но самостоятельно изменить напрямую параметр, переданный ей по значению, функция не может.



Традиционный метод Си для изменения x заключается в использовании в качестве фактического аргумента &x, то есть адреса x, а

не самого значения x. Хотя &x передается по значению, функция получает доступ к x благодаря тому, что ей доступна полученная копия &x. Даже если функции не требуется изменять значения x, тем

не менее полезно (хотя это чревато возможностью нежелательных побочных эффектов) передавать &x, особенно если x представляет собой большую по размерам структуру данных. Передача x непосредственно по значению ведет к бесполезным затратам памяти на копирование такой структуры данных.

Сравним три различных реализации функции treble:

Реализация 1:

int treble_1(n)

{

return 3*n;

}

...

int x, i = 4;

x = treble_1(i); // теперь x = 12, i = 4

...

Реализация 2:

void treble_2(int* np)

{

*np = (*np)*3;

}

...

treble_2(int &i); // теперь i = 12

Реализация 3:

void treble_3(int& n) // n имеет тип ссылки

{

n = 3*n;

}

...

treble_3(i); // теперь i = 36

Объявление формального аргумента type& t (или, что эквивалентно, type &t) устанавливает t как имеющую тип "ссылки на тип type". Поэтому при вызове treble_3 с действительным аргументом i, i используется для инициализации формального аргумента ссылки n.


Следовательно, n играет роль псевдонима i, и n = 3*n также присваивает i значение 3*i.

Если инициализатор представляет собой константу или объект

нессылочного типа, то Borland C++ создаст временный объект, для

которого ссылка действует как псевдоним:

int& ir = 16; /* создается временный объект int, с именем

псевдонима ir, который получает значение

16 */

float f;

int& ir2 = f; /* создается временный объект int, с именем

псевдонима ir2, f перед присваиванием

преобразуется */

ir2 = 2.0 /* теперь ir2 = 2, но f остается без измене-

ний */

Если формальные и фактические аргументы имеют различные (но

совместимые по присваиванию) типы, то автоматическое создание

временных объектов позволяет выполнять преобразования ссылочных

типов. При передаче по значению, разумеется, проблем с преобразованием типов меньше, поскольку перед присваиванием формальному

аргументу копия фактического аргумента может быть физически изменена.


Содержание раздела