Язык программирования C++


Распределение памяти при передаче аргументов функции - часть 2


Complex Complex::Add(Complex& x) { Complex result; result.real = real + x.real; result.imaginary = imaginary + x.imaginary; return result; }

то при вызове n3 = n1.Add(n2) компилятор будет создавать ссылку на переменную n2 и передавать ее методу Add. В большинстве случаев это намного эффективнее, так как для ссылки требуется немного памяти и создать ее проще. Однако мы получим нежелательный в данном случае эффект. Метод

Complex Complex::Add(Complex& x) { Complex result; x.imaginary = 0; // изменение значения // по переданной ссылке result.real = real + x.real; result.imaginary = imaginary + x.imaginary; return result; }

изменит значение переменной n2. Операция Add не предусматривает изменения собственных операндов. Чтобы избежать ошибок, лучше записать аргумент с описателем const, который определяет соответствующую переменную как неизменяемую.

Complex::Add(const Complex& x)

В таком случае попытка изменить значение аргумента будет обнаружена на этапе компиляции, и компилятор выдаст ошибку. Передачей аргумента по неконстантной ссылке можно воспользоваться в том случае, когда функция действительно должна изменить свой аргумент. Например, метод Coord класса Figure записывает координаты некой фигуры в свои аргументы:

void Figure::Coord(int& x, int& y) { x = coordx; y = coordy; }

При вызове

int cx, cy; Figure fig; . . . fig.Coord(cx, cy);

переменным cx и cy будет присвоено значение координат фигуры fig.

Вернемся к методу Add и попытаемся оптимизировать передачу вычисленного значения. Простое на первый взгляд решение возвращать ссылку на результат не работает:

Complex& Complex::Add(const Complex& x) { Complex result; result.real = real + x.real; result.imaginary = imaginary + x.imaginary; return result; }

При выходе из метода автоматическая переменная result уничтожается, и память, выделенная для нее, освобождается. Поэтому результат Add – ссылка на несуществующую память. Результат подобных действий непредсказуем. Иногда программа будет работать как ни в чем не бывало, иногда может произойти сбой, иногда результат будет испорчен. Однако возвращение результата по ссылке возможно, если объект, на который эта ссылка ссылается, не уничтожается после выхода из функции или метода. Если метод Add прибавляет значение аргумента к текущему значению объекта и возвращает новое значение в качестве результата, то его можно записать:




Начало  Назад  Вперед