Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 66
Текст из файла (страница 66)
Например: ооЩ(и1гшуй и1, игг(адй и2, и1гглуйиЗ( соа(«и1- г, игг1лд и = и2»иЗ; (Г (и!еля(Ь (<В йй и(0(=ега( ( ,Г,г агоол»зоеоние и Временная переменная может использоваться в качестве пнпцпалпзатора констант- ной ссылки или именованного объекта. Например: ооо( у (соаи1 и1гсоуй, соои1 игг(оуй) ооЫ Ь (игг!ауй и1, и1г(о уй и2( ( соои1 иггсауй и = и1»и2; и1г(пд'ии = и1+и2; й (и, ии(; //лы можем аспольиоеа!оь ипесь и а ии Все работает отлично. Временная переменная уничтожается, когда «ее» ссылка или именованный объект выходит нз области видимости.
По»шите, что возврат из функции ссылки на локальную переменную является ошибкой Я 7.3), и что неконстантная ссылка не может ссылаться на временную переменную (В 5.5). Временный объект также может быть создан при помощи явного вызова конструктора. Например: ооИ ((Вепрей и, 1лгк, ш1у( 303 10.4. Объекты втоое (Рогат (х, у)), // создается Ронидля переда ш Кларе: зпосе О //- ) Такие временные переменные уничтожаются точно таким же спосооом, как и неявно генерируемые.
10.4.11. Размещение объектов По умолчанию оператор пеш создает объекты в свободной памяти. Что если бы мы захотели поместить такис объекты где-то в другом месте? Рассмотрим простой класс: с(авв Х( риЬйс. Х()пт), //... )' Мы можем поместить объекты куда угодно, написав функцию выделения памяти, имеющую дополнительные аргументы, и затем задавая их при использовании оператора пеш: // оператор явного разлет ения оотг(' орегатог неш (вехе б ооЫ' р) ( гетигп р; ) // некоторый конкрел~ныи адрес оси(' Ьит" = ге!птегргет саве -сои(*» (ОхГООР), // созда иве Х в Ьи/ вызывается арета!отпев~(стево/(Х), Ьн/) Х' р2 = пеш (Ьи)) Х, Из-за своего использования синтаксис пеш (Ьи)) Х, нозволяюший задать дополнительные аргументы для орега1ог пеш (,', называется синтлкгисоги развел(ения. Обратите внимание, что каждый арета(ог лето получает в качестве первого аргумента размер, и что размер размещаемого объекта задается неявно Я 15.6).
Выбор функции орегагог пеш () для вызова оператора пеш цодчнняется обычным цравилам соответствия аргументов (6 7.4); каткдый орегатог лев () имеет в качестве первого аргумента вохе г. Приведенный «оцератор размещения» орега бог пеш () является цростешпцм таким распределителем (а)! оса!от). Он определен в стандартном заголовочном файле <пеш>. Преобразование ге(л(егрге( сав(является самым цодозрнтельным и потенциально наиболее опасным (ь 6.2.7). В большинстве случаев в результате его применения получается значение нужного тина с той же последовательностью битов, что и его аргумент.
Этики преобразованием приходится пользоваться для традиционно опасных, зависящих от реализации, но иногда совершенно необходимых преобразований целых значений в указатели н наоборот. Конструкция размещения леш может использоваться для выделения памяти в конкреттюй области: с)авв Акела ( риЬНс ' Тип всее т является типом значения, возврашаемого функцией в)вел(), см.
й 16.122.— Прилиеч. ред ЗО4 Глава 10. Классы и!г!и а! ооЫ' а!!ос (в!хе !) = 0; гиг!иа! иопЦгее (иоЫ') = О, //- иоЫ' орега!ог лев (в!ге ! ве, Агепи* и) ( ге!иги а->а(!ос )ве), Теперь объекты произвольных типов можно размешать в различных областях памя- ти (варевах»). Например: ех!егл Агела" Регв!в!еи1; ехгегп Агела* Я(!агес(, иоЫХ (и! !) Х" р =- пню )Реев!в!еп!) Х )!), Л у=песо(86агегйХ(!), //- ) ДХ в Режпгегп //Хв 5!гагед Помещение объекта в область, которая (непосредственно) не управляется стандарт- ным распределителем свободной памяти подразумевает определенные действия при уничтожении объекта. Базовым механизмом для этого является явный вызов дест- руктора: ооЫ г!ее!го у )Х' р, А гена' а) ( р->-Х(); // вызов деструктора а->/ ее (), //освооохсденне валянии Обратите внимание на то, что следует избегать явных вызовов деструкторов, равно как и использования глобальных распределителей памяти специального назначения, там где это только возможно.
Но иногда онп требуются. Например, было бы сложно реализовать обобщенный контейнер вес(ог в духе стандартной библиотеки (з 3.7.1, у 16.3.8) без использования явного вызова деструктора. Новичку же стоит дважды (лучше трижды) подумать, прежде чем вызывать деструктор явно лучше проконсультпроваз ься у более опытного коллегц, См. в З 14.4.7 объяснения по поводу того, как размещение оператором леш () взаимолействует с обработкой исключений.
Нет специального синтаксиса для размещения массивов. В нем нет особой необходимости, поскольку с поыошгло леш можно размещать произвольные типы. Однако для массивов можно определить специальный оператор с(е!е(е () (ч' 19А.5). 10.4.12. Объединения Именованным объединением называется структура, в которой каждый член имеет один и тот же адрес (см. З В.8.2). Объединение может иметь функцип-члены, но не статические члены. 10.5. Советы 305 Как правило, компилятор не может знать, какой член объединения используется; то есть тип объекта, хранящегося в объединении, неизвестен.
Следовательно, объединение не может иметь члены с конструкторами и деструкторами. В противном случае было бы невозможно предохранить объект от разрушения или гарантировать, что будет вызван нужный деструктор, когда объединение выйдет за пределы области видимости. Объединения лучше использовать в коде низкого уровня, пли как часть реализации класса, который сохраняет информацию о том, что хранится в объединении (см. э 10.6[20]).
10.5. Советы [1] Г!редставля<1те концепции в виде классов; ч 10.1. [2] Пользуйтесь открытыми даннымн (структурами) только тогда, когда вам нужны действительно только данные н нет никаких ннварпантов для членов данных; э 1 0.2.8. [3] Конкретные типы являк~тся простейшими представнтелямп классов. Там где это возможно, отдавайте предпочтение конкретным гипам по сравнению как с более сложными классами, так и с обычными структурами данных; Э 10.3 [4] Рсалпзуйте функцию в качестве члена, только если ей требуется непосредственный доступ к представлению класса; ~ 10.3.2.
[б] Пользуйтесь пространством имен для явного выражения связи между классом и функциями-помощнпками; э 10.3.2. [6] Объявляйте функцикъчлен как константную (сопя<), если она не должна люднфицировать значение объекта; ([ 10,2.6. [7[ Объявляйте функцию-член как статическую (я<а<<с), если ей требуется доступ к представлению класса, но ее не требуется вызывать для конкретного объекта класса: 5 10.2А. [8] Пользуйтесь конструктором для установления пнварианта класса; ~ 10.3.1. [9[ Если конструкторутребуется какой-нибудь ресурс, в классе необходиью внести деструктор для освобождения этого ресурса; 6 10А.1. [10[ Если в классе имеется член, являкпцпйся указателем, ему требуются копирующие операции <копирующий конструктор и копирую|цее присванванпе); ьч 10АА.1.
[11] Если в классе имеется член, являюп<ийся ссылкой, ему вероятно потребуются коппру|ошпе операции (копирующий конструктор и копирующее присваивание); ~ч 10 4.6.3. [12] Если классу требуется копирующая операция пли деструктор, ему вероятно потребуются конструктор, деструктор, когшруюшпй конструктор и копирующее прпсванванне; ([ 10АА.1. [13] Проверяйте, нет лп присваивания самому себе прп копирующем присваивании; 6 10.4А.1. [14] Прн написания копирующего конструктора, проследите за тем, чтобы были скопированы все требуемые элементы (не забывайте об инициалпзаторах по умолчанию); э 10А.4.1.
[15] При добавлении в класс нового члена всегда проверяйте, не надо ли модифицировать для инициал изапип этого члена определяемые пользователем конструкторы; ~ 10А 6.3, Глава 10. Классы 306 [16] Пользуйтесь перечисленнял1п для определения целых констант в объявлениях кчасса; ьз 10А.6.2. [17] Избегайте зависимости от порядка создания глобальных объектов и объектов в пространствах и»зев; 9 10.4,9, [18] Пользуйтесь индикаторами первого использования для минимизации зависимости от порядка; 6 10.4.9. [19] Помните, что временные объекты уничтожаются в конце обработки полного выражения, в котором онн созданы; 9 10А.10. 10.6.
Упражнения 1, (*1) Найдите ошибку в Ра1е: ас(г1 деаг [) в 9 10.2.2. Найдите еше две ошибки в версии в 9 10.2.7. 2. (»25) Завершите и протестнруите Расе. Реализуйте этот класс в представлении «количество дней после 1/1/1970». 3. (*2) Найдите коммерческий класс Ра1е. Покритикуйте средства, используемые в нем. Если возможно, обсудите его с реальным пользователем. 4. ("1) Как вы обратитесь к ве( де(аи11 из класса РаГе, находяшимся в пространстве имен С(сгопо Я 10З.2)? Предложите по крайней мере трп различных способа. 5.