Эффективный и современный C++ [Скотт Мейерс] (pdf) читать постранично, страница - 4

-  Эффективный и современный C++  (пер. И. В. Красиков) 12.86 Мб, 306с. скачать: (pdf) - (pdf+fbd)  читать: (полностью) - (постранично) - Скотт Мейерс

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

инварианты программы останутся нетронутыми
(т.е. не будут повреждены структуры данных) и не будет никаких утечек ресурсов. Функ­
ции, обеспечивающие строгую гарантию, гарантируют, что, даже если будет сгенериро­
вано исключение, состояние программы останется тем же, что и до вызова функции.
Говоря о функциональном объекте, я обычно имею в виду объект типа, поддержи­
вающего функцию-член operator (). Другими словами, это объект, действующий, как
функция. Иногда я использую термин в несколько более общем смысле для обозначения
чего уrодно, что может быть вызвано с использованием синтаксиса вызова функции, не
являющейся членом (т.е. function Name (arguments) ). Это более широкое определе­
ние охватывает не только объекты, поддерживающие operator (), но и функции и ука­
затели на функции в стиле С. (Более узкое определение происходит из С++98, более ши­
рокое - из C++ll.) Дальнейшее обобщение путем добавления указателей на функции­
члены дает то, что известно как вызываемый объект (callaЫe object). Вообще говоря,
-

18

В ведение

можно иrнорировать эти тонкие отличия и просто рассматривать функциональные и вы­
зываемые объекты как сущности в С++, которые моrут быть вызваны с помощью неко­
торой разновидности синтаксиса вызова функции.
Функциональные объекты, создаваемые с помощью лямбда-выражений, известны как
замь1кания (closures). Различать лямбда-выражения и замыкания, ими создаваемые, при­
ходится редко, так что я зачастую rоворю о них обоих как о лямбдах (lambda). Точно так
же я редко различаю шаблоны функций (fuпction templates) (т.е. шаблоны, которые rе­
нерируют функции) и шаблонные функции (template ftшctions) (т.е. функции, сrенериро­
ванные из шаблонов функций). То же самое относится к шаблонам классов и шаблонным
классам.
Мноrие сущности в С++ моrут быть как объявлены, так и определены. Объявления
вводят имена и типы, не детализируя информацию о них, такую как их местоположение
в памяти или реализация:
extern int

х;

class Widget ;

11 Объявление объекта
11 Объявление класс а

bool func ( const Widget& W); 11 Объявление функции
enшn class Color;

11 Объявление перечисления
11 с областью видимости
11 ( см. раздел 3.4)

Определение предоставляет информацию о расположении в памяти и деталях реализации:
int

х;

cla ss Widget
)

11 Определение объекта
11 Определение класса

;

bool func ( const Widget& w)
{ return w . size ( ) < 1 0 ; 1 // Определение функции
enurn class Color
{ Yellow, Red, Blue f ;

11 Определение перечисления

Определение можно квалифицировать и как объявление, так что, если только то, что
нечто представляет собой определение, не является действительно важным, я предпочи­
таю использовать термин "объявление·:
Сигнатуру функции я определяю как часть ее объявления, определяющую типы
параметров и возвращаемый тип. Имена функции и параметров значения не име­
ют. В приведенном выше примере сиrнатура функции func представляет собой
bool (const Widget&) . Исключаются элементы объявления функции, отличные от ти­
пов ее параметров и возвращаемоrо типа (например. noexcept или constexpr, если
таковые имеются). (Модификаторы noexcept и constexpr описаны в разделах 3.8

В ведение

19

и 3.9.) Официальное определение термина "сигнатура" несколько отличается от моего,
но в данной книге мое определение оказывается более полезным. (Официальное опреде­
ление иногда опускает возвращаемый тип.)
Новый стандарт С++ в общем случае сохраняет корректность кода, написанного для бо­
лее старого стандарта, но иногда Комитет по стандартизации не рекомендует применять те
или иные возможности. Такие возможности находятся в "камере смертников" стандартиза­
ции и могут быть убраны из новых версий стандарта. Компиляторы могут предупреждать
об использовании программистом таких устаревших возможностей (но могут и не делать
этого), но в любом случае их следует избегать. Они могут не только привести в будущем
к головной боли при переносе, но и в общем случае они ниже по качеству, чем возмож­
ности, заменившие их. Например, st d : : a ut o _pt r не рекомендуется к применению
в C++ l l , поскольку std:: unique_pt r выполняет ту же работу, но лучше.
Иногда стандарт гласит, что результатом операции является неопределенное поведе­
ние (undefined behavior). Это означает, что поведение времени выполнения непредсказу­
емо, и от такой непредсказуемости, само собой разумеется, следует держаться подальше.
Примеры действий с неопределенным поведением включают использование квадратных
скобок ( []) для индексации за границами std: :vec t o r, разыменование неинициали­
зированного итератора или гонку данных (т.е. когда два или более потоков, как минимум
один из которых выполняет запись, одновременно обращаются к одному и тому же ме­
сту в памяти).
Я называю встроенный указатель, такой как возвращаемый оператором new, обычным
указателем (raw pointer). Противоположностью обычному указателю является интеллек­
туальный указатель (smart pointer). Интеллектуальные указатели обычно