Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ — страница 73 из 74

ной из таких библиотек является Conversion, которая представляет безопасные и более удобные операторы приведения. Например, входящая в нее функция numeric_cast возбуждает исключение, если преобразование одного числового типа в другой приводит к переполнению, потере значимости либо другим подобным проблемам, а функция lexical_cast позволяет привести любой тип, поддерживающий operator<<, к строке, что очень удобно для диагностики, протоколирования и т. п. Другую крайность составляют библиотеки, представляющие настолько широкие возможности, что им можно посвящать целые книги. Это относится к библиотеке Boost Graph Library (для программирования произвольных структур графов), и Boost MPL Library («библиотека метапрограммирования»).

Библиотеки Boost посвящены самым разным темам, сгрупированным в несколько основных категорий:

Обработка строк и текстов. Сюда входят библиотеки для безопасного по отношению к типам форматирования (по аналогии с printf), работы с регулярными выражениями (легли в основу соответствующей функциональности TR1 – см. правило 54), а также лексического и грамматического анализа.

Контейнеры. Сюда входят библиотеки для работы с массивами фиксированной длины с STL-подобным интерфейсом (см. правило 54), битовыми наборами произвольной длины, а также многомерными массивами.

Функциональные объекты и высокоуровневое программирование. Эта категория объединяет несколько библиотек, которые лежат в основе функциональности TR1. Одной из наиболее интересных является библиотека Lambda, которая настолько упрощает создание функциональных объектов на лету, что вы вряд ли даже осознаете, что происходит:


using namespace boost::lambada; // включить средства

// из библиотеки Lambda

std::vector  v;

...

std::for_each(v.begin(), v_end(), // для каждого элемента x

std::cout <<_1*2+10<<”\n”); // в v напечатать x*2+10;

// “_1” – место для

// подстановки текущего

// элемента


Обобщенное программирование. Сюда входит широкий набор классов-характеристик (см. правило 47).

Метапрограммирование шаблонов (TMP – см. правило 48). Включает библиотеку утверждений (assertions) времени компиляции, а также библиотеку Boost MPL Library. Среди прочего она поддерживает STL-подобные структуры данных, описывающие сущности времени компиляции, к примеру типы:


// создать контейнер времени компиляции, подобный списку, содержащий

// три типа (float, double и long double), и назвать его “floats”

typedef boost::mpl::list floats;

// создать новый контейнер времени компиляции, содержащий типы

// из “floats”, плюс “int”, вставленный в начало; назвать новый

// контейнер “types”

typedef boost::mpl::push_front::type types;


Такие контейнеры типов (их часто называют спискамии типов – typelists, хотя они могут быть основаны не только на классе mpl::list, но и на mpl::vector) открывают возможность написания широкого диапазона мощных и полезных TMP-приложений.

Математика и численные методы. Сюда входят библиотеки для работы с рациональными числами, поиска наибольшего общего делителя и наименьшего общего кратного, а также для операций со случайными числами (еще одна библиотека, оказавшая влияние на включение соответствующей функциональности в отчет TR1).

Корректность и тестирование. Сюда входят библиотеки для формализации неявных шаблонных интерфейсов (см. правило 41) и поддержки программирования на основе методологии «тестирования с самого начала».

Структуры данных. Сюда отнесены библиотеки для поддержки безопасных по отношению к типам объединений (то есть «любых» неоднородных типов) и библиотека кортежей, которая нашла применение в TR1.

Межъязыковая поддержка. Содержит библиотеку, обеспечивающую «бесшовное» взаимодействие между программами, написанными на языках C++ и Python.

Память. Сюда входит библиотека Pool для высокопроизводительных распределителей памяти блоками фиксированного размера (см. правило 50), а также целый ряд «интеллектуальных» указателей (см. правило 13), включая те, что вошли в TR1 (но не только). Одними из таких «интеллектуальных» указателей, не включенных в TR1, являются scoped_array – похожая на auto_ptr конструкция для динамически выделенных массивов; в правиле 44 приведен пример его использования.

Разное. К этой категории отнесены библиотеки для вычисления CRC, манипуляций с датами и временем, а также прохода по файловой системе.

Это всего лишь небольшая часть библиотек, которые имеются на сайте проекта Boost. Список далеко не полный.

Boost предлагает библиотеки для решения самых разных задач, но они, конечно, не покрывают всех тем, которыми занимаются программисты. Так, например, нет библиотеки для разработки графических интерфейсов, как нет и библиотек для доступа к базам данных. По крайней мере, их нет сейчас (когда я пишу эти строки). Но к тому времени, когда вы будете читать эту книгу, они могут появиться. Единственный способ узнать точно – зайти на сайт и проверить. Надеюсь, вы сделаете это прямо сейчас: http://boost.org. Даже если вы не найдете там в точности того, что ищете, все равно обязательно обнаружите что-то интересное для себя.

Что следует помнить

• Boost – это сообщество и Web-сайт для разработки бесплатных библиотек на C++ с открытыми исходными текстами, подвергающихся публичному обсуждению. Boost оказывает немалое влияние на процедуру стандартизации C++.

• Boost предоставляет реализацию многих компонентов TR1, но – кроме того – и множество других библиотек.

Приложение АЗа пределами «Эффективного использования C++»

В книгу «Эффективное использование C++» вошло то, что я считаю наиболее важными рекомендациями для практикующих программистов на C++. Если вы интересуетесь дополнительными возможностями повысить эффективность своей работы, я рекомендую ознакомиться с другими моими книгами: «Наиболее эффективное использование C++» и «Эффективное использование STL».

В книгу «Наиболее эффективное использование C++» включены дополнительные рекомендации и подробно рассмотрены такие темы, как эффективность и программирование с учетом исключений. Кроме того, в ней описываются такие важные приемы программирования на C++, как «интеллектуальные» указатели, подсчет ссылок и прокси-объекты.

«Эффективное использование STL» – это тоже набор рекомендаций, организованный подобно «Эффективному использованию C++», но основное внимание в ней уделено применению стандартной библиотеки шаблонов.

Содержание обеих книг приведено ниже.

Наиболее эффективное использование C++

Основы

Параграф 1: Различайте указатели и ссылки

Параграф 2: Предпочитайте приведение типов в стиле C++

Параграф 3: Никогда не используйте полиморфизм в массивах

Параграф 4: Избегайте неоправданных конструкторов по умолчанию

Операторы

Параграф 5: Опасайтесь определяемых пользователем функций преобразования типов

Параграф 6: Различайте префиксную и постфиксную формы операторов инкремента и декремента

Параграф 7: Никогда не перегружайте «&&», «||» или «,»

Параграф 8: Различайте значение операторов new и delete

Исключения

Параграф 9: Чтобы избежать утечки ресурсов, используйте деструкторы

Параграф 10: Не допускайте утечки ресурсов в конструкторах

Параграф 11: Не распространяйте обработку исключений за пределы деструктора

Параграф 12: Отличайте генерацию исключения от передачи параметра или вызова виртуальной функции

Параграф 13: Перехватывайте исключения, передаваемые по ссылке

Параграф 14: Разумно используйте спецификации исключений

Параграф 15: Оценивайте затраты на обработку исключений

Эффективность

Параграф 16: Не забывайте о правиле «80–20»

Параграф 17: Используйте отложенные вычисления

Параграф 18: Снижайте затраты на ожидаемые вычисления

Параграф 19: Изучите причины возникновения временных объектов

Параграф 20: Облегчайте оптимизацию возвращаемого значения

Параграф 21: Используйте перегрузку, чтобы избежать неявного преобразования типов

Параграф 22: По возможности применяйте оператор присваивания вместо отдельного оператора

Параграф 23: Используйте разные библиотеки

Параграф 24: Учитывайте затраты, связанные с виртуальными функциями, множественным наследованием, виртуальными базовыми классами и RTTI

Приемы

Параграф 25: Делайте виртуальными конструкторы и функции, не являющиеся членами класса

Параграф 26: Ограничивайте числа объектов в классе

Параграф 27: В зависимости от ситуации требуйте или запрещайте размещать объекты в куче

Параграф 28: Используйте интеллектуальные указатели

Параграф 29: Используйте подсчет ссылок

Параграф 30: Применяйте прокси-классы

Параграф 31: Создавайте функции, виртуальные по отношению более чем к одному объекту

Разное

Параграф 32: Программируйте, заглядывая в будущее

Параграф 33: Делайте нетерминальные классы абстрактными

Параграф 34: Умейте использовать C++ и C в одной программе

Параграф 35: Ознакомьтесь со стандартом языка

Эффективное использование STL

Глава 1: Контейнеры