Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 106
Текст из файла (страница 106)
Объясните, как мог бы быть реализован вызов виртуальной функции. 11. ('3) Подумайте, как можно реализовать динамическое приведение «7упат(с саз(. Спроектируйте и реализуйте шаблон с(сааб который ведет себя как Нупат1с сааб но использует прп этом только данные и функции, определенные вами. Убсдитесгь что вы можете добавить новые классы в систему, нс меняя при этом определение «1саФ или ранее написанных классов. 12. (*2) Предположим, что правила проверки типов для аргументов были ослаблены, аналогично правилам для типов возвращаемых значений таким образом, что функция с аргументом Пеппер' (указатель ца производный класс) может заместить функцию с аргументом Вазе* (указатель на базовый класс).
Затем напишите программу, которая может разрушить объект класса Оепиед без использования приведения типа. Опишите безопасное ослабление правил замегцения для типов аргументов. ЧАСТБ ТРЕ ПъЯ ТАНДАРТНАЯ БИБЛИОТЕКА В этой части описывается стандартная библиотека С++, Читатель знакомится с построением библиотеки и с ключевыми приемами для ее реализации.
Цель этой главы — объяснить, как следует пользоваться стандартной библиотекой, в общих чертах продемонстрировать полезные приемы проектирования и программирования, а также показать, каким образом расширять библиотеку в соответствии с замыслом ее создания. 16. Организация библиотеки и контейнеры 17. Стандартные контейнеры 18. Алгоритмыи объекты-функции ... 19. Итераторы н распределители памяти 20. Строки .
21. Потоки 22. Численные методы Организация библиотеки и контейнеры Это бьао аово. Э>по было своеобразно. Э>по было проппа. Э>по должно было получиться! — !'. Нельсон Критерии проскгирования стандартной биб пиотеки — организация библиотеки— стандартные заголовочные файлы — языковая поддержка — проектирование контейнеров — итераторы — базовые контейнеры — БТ).-контейнеры — вектор (оес1ог) — итераторы — доступ к элементам — конструкторы — модифпкаторы— операции со списками — размер и емкость — пес!ог«Ьоо!> — советы — упражнения.
16.1. Проектирование стандартной библиотеки «1то должно быть в стандартной библиотеке? Для программиста идеалом было бы найти в библиотеке все интересные, нужные и достаточно общие классы, функции. шаблоны и т. д. Однако вопрос не в том «Что должно быть в неко>порой библиотеке? >, но «Что должно быть в стандартной библиотеке?» Ответ «ВсеЬ> в первом приближении имеет смысл для первого вопроса, но не для второго. Стандартная библиотека — зто нечто такое, что должно быть обеспечено в каждой реализации языка, чтобы потом все программисты могли на нее опираться. Стандартная библиотека С++: [1) Обеспечивает поддержку свойств языка, таких как управление памятью Я 6.2.6) и информация о типах во время выполнения Я! 5 4).
[2] Предоставляет информацию о зависящих от реализации аспектах языка, таких, например, как максимальное значениеЯоа( Я 22.2). [3[ Прслоставляет функции, которые не могут быть написаны оптимально для всех систем собственно на языке С++, например здг( [[ Я 22 3) или гаетгаоое ([ (з 19 4 6). [4[ Предоставляет программисту нетривиальные средства, на которые он сможет рассчитывать, заботясь о переносимости такие, как списки Я 17.2.2), отображения (ассоцнативные массивы) (6 17.4.1), функции сортировки Я 18.7.1) и потоки ввода/вывода (глава 21). [5[ Дает основу для расширения своих возможностей, такую как соглашения и средства поддержки, которые позволяют пользователю обеспечить ввод>>вывод для определяемых им типов в стиле ввода/вывода для встроенных типов. [6[ Служит общим фундаментом для других библиотек.
Глава 16. Организация библиотеки и контейнеры 486 Кроме того, стандартная библиотека предоставляет некоторые программные средства — например, генератор случайных чисел Я 22.7) — просто потому, что так принято, и это удобно, Проект библиотеки первоначально определялся последними тремя ролями, которые тесно связаны между собой. Например, переносимость обычно является важным критерием проектирования для спепиальных библиотек, а общие контеццерныс типы, такие как списки п ассоциативные массивы, существенны для удобной связи между раздельно разрабатываемыми библиотеками. С точки зрения проектирования особенно важна последняя роль, поскольку она помогает ограничить область применения стандартной библиотеки и налагает ограничения на ее средства. Например, стандартной библиотекой предоставляются строки и списки.
Если бы их пе было, независимо разработанные библиотеки могли бы общаться между собой, только используя встроенные типы. Однако распознавание образов и графика станлартной онблиотекой не обеспечиваются. Эти возможности, очевидно, весьма полезны, но они редко участвуют непосредственно во взаимодействии независимо разработанных библиотек. Если какое-то средство не нужно для ооеспечения хотя бы одной из вышеперечисленных ролей, его можно оставить за пределами стандартной библиотеки.
К счастью илп нет, оставление чего-то за пределами стандартной библиотеки открывает другим библиотекам возможность конкурировать прн ее реализации. 16.1.1. Проектные ограничения Задачи стандартной биолпотекп налагают на пее ряд проектных ограничений. Пред- лагаемые стандартной библиотекой С++ средства спроектированы так, чтобы: [1] Быть важными и доступпымн для каждого студента и профессионального программиста, в том числе для создателей других библиотек, [2] Прямо или косвенно использоваться всеми программистами для решения всех задач, которые связаны с целями библиотеки. [3] Быть достаточно эффективпьжш, чтобы при реализации будущих библиотек обеспечить достойную альтернативу функциям, классам и шаблонам, программируемым вручную.
[4] Быть независимыми от алгоритмов нли предоставлять пользователю возможность задавать алгоритм в качестве аргумента. [5] Быть примитпвнымн в математическом смысле. То есть компонента, которая играет две лило связанные между собой роли, будет почти наверняка вызывать лишние затраты по сравнению с двумя отдельными компонентамп, призванными играть каждый свою олпу четко определенную роль. [6] Быть удобными, эффективными и достаточно безопасными прн использовании в большинстве тшшчцых случаев. [7] Быть завершеннымп в том, что делают. Стандартная библиотека может оставить множество функций другим библиотекам, но если уж она взялась за какую-то задачу, то должна обеспечить достаточную функциональность, чтобы отдельным пользователям и разработчикам не приходилось заменять ее средства.
[8] Хорошо сочетаться и дополнять встроенные типы и операции, [9] Быть безопасными по умолчанию с точки зрения типов. 18.1. Проектирование стандартной библиотеки 487 (10( Поддергкивать общепринятые стили программирования. [11~ Быть способными к расширению, чтобы работать с типами, определяемыми пользователем, так гкс, как со встроенными типами и типами из стандартной библиотеки. Например, встраивание критериев сравнения в функцию сортировки недопустимо, поскольку те же данные могут сортироваться в соответствии с какими-либо другими критериями.
Вот почему стандартная библиотечная функция С дзог(0 получает функцию сравнения в качестве аргумента, а не использует нечто фиксированное— скажем, оператор < Я 7.7). С другой стороны, излишние затраты, на.лагаемые вызовом функции для каждого сравнения, компрометируют дзог(() с ~очки зрения дальнейшего построения библиотеки. Почти для каждого типа данных легко реализовать сравнение без лишних затрат на вызов функции.
Серьезны лн эти затраты? Вероятно, в большинстве случаев нет. Однако в некг— торых алгоритмах вызовы функций могут занять значительное время и заставить пользователя искать альтернативу. Задание критерия для сравнения через аргумент н«аблона, описанное в з 13А, решает эту проблему. Данный пример иллюстрирует конфликт между эффективносзью и универсальностью. От стандартной библиотеки не просто требуется выполнять свои задачи, она также должна выполнять их достаточно эффективно, чтобы у пользователя не возникло соблазна использовать собственные механизмы. Иначе разработчики более продвинутых средств, чтобы остаться конкурентоспособными, будут вынуждены отказаться от стандартной библиотеки. Это добавило бы хлопот разработчику библиотеки и серьезно усложнило бы жизнь пользователям, желающим оставаться независящими от платформы или использовать несколько раздельно разработанных онблиотек. Требования «примитивности» и «улобства прн типовом использовании» кажутся противоречивыми.
Последнее требозание запрещает излишнюю оптимизацию стандартной библиотеки для общих случаев. Однако необходимо иметь возможность включать в стандартную библиотеку (в дополнение к примитивным возможностям, а не взамен) компоненты, гщужшцие часто встречшощимся (но не примьггивным) целям. Культ ортогональности це должен удерживать нас от того, чтобы сделать жизнь новичка или случайного пользователя удобной. И мы не должны из соображений ортогональности оставлять действия компонент по умолчанию неясными или опасными.