|
Программирование >> Оптимизация возвращаемого значения
□ поддержка ввода/вывода. Библиотека iostream остается частью стандарта С++. Хотя некоторые классы и были исключены (в частности классы iostream и f stream), а некоторые заменены (например, stringstream, основанный на классе string, занял место устаревшего strstream, основанного на char*), главные возможности стандартных классов библиотеки iostream отражают уже существующие реализации; □ поддержка вычислительных приложений. Комплексные числа наконец помещены в стандартную библиотеку. Кроме того, библиотека теперь содержит специальные классы массивов (valarray), ограничивающие совместное использование. Эти массивы более подходят для эффективной оптимизации, чем встроенные массивы, особенно в многопроцессорных архитектурах. Библиотека также предоставляет несколько полезных численных функций; □ поддержка универсальных контейнеров и алгоритмов. В стандартной библиотеке С++ содержится набор классов и шаблонов функций, которые известны как стандартная библиотека шаблонов (the Standard Template Library - STL). Стандартная библиотека шаблонов является наиболее революционной частью библиотеки С++. Ее основные черты рассматриваются ниже. Но прежде чем описать STL, я должен рассказать о двух характерных чертах стандартной библиотеки С++, о которых вы должны знать. Во-первых, почти все в библиотеке является шаблоном. В книге я говорил о стандартном классе string, но фактически такого класса не существует. Вместо него есть шаблон класса с именем basic string, представляющий последовательности символов, и этот шаблон принимает в качестве параметра тип символов, образующий такую последовательность. Это позволяет создавать строки из символов любых видов (символов двойной ширины, символов Unicode и т.д.). То, что мы обычно представляем себе в виде класса string, на самом деле является экземпляром шаблона basic string<char>. Поскольку он часто используется, в стандартной библиотеке шаблонов определяется тип: typedef basic string<char> string; Даже такая запись скрывает многие детали, поскольку шаблон basic string имеет три аргумента, все из которых, кроме первого, имеют значения по умолчанию. Для того чтобы действительно понять код типа string, нужно увидеть полное, без пропусков, объявление basic string: template<class charT, class traits = string char traits<charT>, class Allocator = allocator> > class basic string; Чтобы использовать тип string, вам не обязательно понимать этот бессмысленный набор слов: хотя тип string и является определением типа для экземпляра адского шаблона, он ведет себя так же, как скромный класс без шаблона, на который он похож благодаря определению typedef. Просто сохраните в дальнем уголке мозга запись о том, что если вам когда-либо понадобится изменить тип символов в строках, или тонко настроить параметры символов, или управлять выделением памяти для строк, то вы сможете сделать это при помощи шаблона basic string. Подход, принятый при разработке типа string - обобщить его в шаблоне, -повторяется во всей стандартной библиотеке С++. Потоки ввода/вывода? Они также являются шаблонами; параметр типа определяет тип образующих потоки символов. Комплексные числа? Тоже шаблоны; параметр типа определяет, как должны записываться компоненты чисел. Массивы valarray? Шаблоны; параметр типа определяет, что находится в каждом из массивов. И, конечно же, стандартная библиотека почти полностью состоит из шаблонов. Если вы чувствуете себя не слишком свободно при работе с шаблонами, сейчас как раз подходящее время для того, чтобы их освоить. Нужно знать еще, что почти все в стандартной библиотеке находится в пространстве имен std. Чтобы использовать что-то из стандартной библиотеки, не задавая имя полностью, вам придется задействовать директиву using или (что предпочтительнее) объявление using. К счастью, эти синтаксические операции выполняются автоматически, когда вы включаете в код соответствующие заголовки с помощью директивы # include. Стандартная библиотека шаблонов Самые значительные изменения произошли в стандартной библиотеке шаблонов (Standard Template Library, сокращенно STL). (Так как почти все в библиотеке С++ является шаблонами, название STL не слишком удачно. Но поскольку для части библиотеки, содержащей контейнеры и алгоритмы, это название стало уже привычным, его все и используют, не обращая внимания на то, хорошо оно подходит или плохо.) Вероятно, STL повлияет на развитие большинства библиотек С++, поэтому важно, чтобы вы знали ее основы. Стандартная библиотека шаблонов базируется на трех фундаментальных понятиях: контейнеры, итераторы и алгоритмы. Контейнеры содержат наборы объектов. Итератор - это объекты, похожие на указатели и позволяющие перемещаться по контейнерам STL так же, как указатели позволяют перемещаться по встроенным массивам. Алгоритмы представляют собой функции, которые работают с контейнерами STL и используют итераторы. Проще всего разобраться в принципе действия STL, если вспомнить главное правило С++ (и С) для работы с массивами; указатель на массив может указывать на любой элемент массива или на элемент сразу за концом массива. Если указатель ссылается на элемент, расположенный сразу за концом массива, то его можно сравнивать только с другими указателями на массив; результат его разыменования не определен. Воспользовавшись этим правилом, можно написать функцию, находящую в массиве определенное значение. Для массива целых чисел она будет выглядеть, например, так: int * finddnt *begin, int *end, int value) { while {begin != end && *begin != value) ++begin; return begin; Эта функция ищет элемент со значением value в диапазоне от begin до end (исключая end, который указывает на элемент сразу за концом массива) и возвращает указатель на первый встретившийся элемента массива со значением value; если такой элемент не будет найден, функция возвращает end. Возврат end кажется довольно странным способом сообщить о бесплодном поиске. Не лучше ли было бы возвращать О (нулевой указатель null)? Конечно, значение null более привычно в подобной ситуации, но это не делает его Л5-ше . Функция find должна возвращать некоторое особенное значение указателя, обозначающее неудачное завершение поиска, а для такой цели указатель end подходит ничуть не хуже, чем нулевой указатель. Кроме того, как вы вскоре увидите, указатель end Л5Д1ше обобщает другие типы контейнеров, чем нулевой указатель. Возможно, вам никогда и не понадобится писать функцию find, но такой подход достаточно разумен и прекрасно обобщается. Если вы выполнили этот простой пример, значит, уже овладели большинством идей, на которых основана библиотека STL. Вы можете использовать функцию find так: int values[50]; int *firstFive = find(values, values+50, 5); if (firstFive != values+50) { } else { Поиск в диапазоне values[0]-values[49] значения 5. Был ли поиск успешным? Да. Нет, поиск был неудачным. Вы также можете с помощью функции find осуществлять поиск в поддиапазоне массива: int *firstFive = find{values, values+10, 5) ; int age = 36; Поиск в диапазоне values[0]-values[9] значения 5. int *firstValue = find{values+10, values+20, age) ; Поиск в диапазоне values[10]-values[19] значения age. В функции find нет ничего, что бы ограничивало ее применимость к массивам целых чисел, поэтому по сути она является шаблоном: template<class Т> Т * find{T *begin, Т *end, const Т& value)
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |