Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Глава 24. Перегрузка операторов 269




return

}

Проблема в том, что в результате такого простого присвоения, как         = u2

u3; , будут изменены значения и ul и и2.

Чтобы избежать этого, operator+( ) должен создавать временный объект, в кото- ром и будет сохранен результат сложения. Поэтому operator + () конструирует собст- венный объект, который возвращается этой функцией.

Однако при этом нельзя забывать и       кое-что! Например, приведенный ниже фрагмент работать не будет.

 

{

unsigned cents        + int dollars =

cents);

return result

 

Распространенная ошибка 1. Хотя этот фрагмент

общений об ошибке,                 выполнения этой функции будет весьма чевным. Проблема в том, что возвращается ссылка на объект

рый является локальным для данной функции. Таким образом, к тому вре- мени,  как   функция сможет использовать возвращаемый результат, объект resul t уже выйдет из области видимости.

Тогда почему бы нам не выделить блок памяти из кучи так, как это сделано в при- веденном ниже примере?

USDollarS

f

in t cents                +

unsigned in t  dollar s  =                                         dollars ; return cents) ;

 

Распространенная ошибка 2, Вы, конечно, можете вернуть ссылку на объ- ект, память под который была выделена из кучи, однако возникнет новая проблема: при этом не предусматривается механизм возврата памяти в кучу. Эта ошибка называется  и ее очень сложно отыскать. Хотя такой оператор и  будет работать, он будет потихоньку "истощать" память в куче при каждом выполнении сложения.

Возврат по значению заставляет компилятор создавать временный объект в стеке вызывающей функции. Затем созданный функцией объект копируется в этот времен- ный объект.

Возникает вопрос: как долго существует временный объект, который воз- вращает operator + () ? Изначально это не было определено, однако затем создатели стандартов собрались вместе и решили, что такой временный объект остается необходимым до завершения развернутого выражения. Развернутое выражение — это все, что находится перед точкой с запятой. Рассмотрим, например, такой фрагмент:

 

LotsClass g 0 ; fn()

 

27 0                                                                                             ЧастьV.Полезныеособен


i;

i   f ! )         - g {) ) ;

}

Временный объект, возвращенный функцией f () , существует, пока выполняется

функция д( ) и пока выполняется умножение.  Там,         стоит точка с запятой, этот объект уже недоступен.

 

operator++()

В отличие от                      (), функция                        (} модифицирует свой аргумент. А значит, вам не нужно создавать временный объект или  возвращать                                       по значению. Вычисляемый результат можно хранить прямо в s. Вызывающей функции может быть возвращен предоставленный оператору аргумент.

//это будет отлично работать

s)

{

 

if         100)

{

 

}

 


}

 

ошибку.


 

приведенный ниже пример, который содержит одну очень хитрую


//это не очень      версия USDollar  s)

{

s.cents**;

if       >= 100)

{

cents-=100;

 

}

return s;

 

Распространенная ошибка                       Возвращая s  значению, функция застав- ляет компилятор генерировать копию объекта. Это отлично сработает в вы- ражениях типа  а  =                                                       но что будет с  выражениями типа                                               Мы ожидаем, что а будет увеличено на 2. Однако при приведенном выше пере- определении этого оператора, объект а будет увеличен на 1, а затем на 1 бу- дет увеличена его копия, а не сам объект а.

Конструкция вида +* (*+а) не очень распространена, но все же допустима. В лю- бом случае имеется еще множество примеров, в которых такой оператор не будет ра- ботать правильно.

Можно сформулировать следующее правило: если оператор изменяет значе- ние своего аргумента, возвращайте аргумент по ссылке. Если оператор не изменяет значения своих аргументов, создавайте новый объект и возвращай- те его по значению. Входные аргументы лучше всегда передавать по ссылке.


Поделиться:



Последнее изменение этой страницы: 2019-04-19; Просмотров: 200; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.011 с.)
Главная | Случайная страница | Обратная связь