Программирование >>  Операторы преобразования типа 

1 ... 40 41 42 [ 43 ] 44 45 46 ... 239


зевание умного указателя с подсчетом ссылок (умного указателя, который автоматически уничтожает связанный объект при уничтожении последней ссылки на него) вызовет немало проблем. Например, при прямом доступе к элементам возможна модификация их значений, пока они находятся в контейнере. В ассоциативном контейнере это приведет к нарушению порядка следования элементов, а это недопустимо.

На с. 226 приведена дополнительная информация о контейнерах со ссылочной семантикой и продемонстрирован один из возможных способов реализации ссылочной семантики для контейнеров STL на базе умных указателей с подсчетом ссылок.

Ошибки и исключения внутри STL

Ошибки случаются, хотим мы того или нет. Они могут быть обусловлены как действиями программы (а точнее, программиста), так и контекстом или рабочей средой программы (например, нехваткой памяти). Обе разновидности ошибок обрабатываются при помощи исключений (начальные сведения об исключениях приводятся на с. 31). Данный раздел посвящен принципам обработки ошибок и исключений в STL.

Обработка ошибок

при проектировании STL главным приоритетом была максимальная произ-водигельность, а не безопасность. Проверка ошибок требует времени, поэтому в STL она практически не выполняется. Если вы умеете программировать без ошибок, все замечательно, а если нет - дело кончится катастрофой. Перед включением библиотеки STL в стандартную библиотеку С++ обсуждался вопрос о том, не нужно ли расширить обработку ошибок. Большинство высказались против по двум причинам.

О Обработка ошибок снижает быстродействие, а высокая скорость работы попреж-нему остается основной целью большинства про1рамм. Как упоминалось выше, быстродействие было одним из приоритетов при проектировании STL.

О Тот, кто ставит на первое место надежность, может добиться своего при помощи интерфейсных оболочек или специальных версий STL. С другой стороны, невозможно повысить быстродействие за счет отказа от проверки ошибок, если эта проверка включена во все базовые операции. Например, если при любой выборке элемента по индексу проверяется, принадлежит ли индекс к интервалу допустимых значений, вам не удастся написать собственную процедуру индексации без проверки. А вот обратная ситуация вполне возможна.

В результате проверка ошибок в STL возможна, но не обязательна.

В спецификации стандартной библиотеки С++ указано, что любое использование STL, нарушающее предварительные условия, приводит к непредсказуемому поведению. Следовательно, при недействительном индексе, итераторе или



интервале может произойти все что угодно. Если не использовать безопасную версию STL, обычно дело кончается нарушением защиты памяти с неприятными побочными эффектами и даже сбоем программы. В некотором смысле применение библиотеки STL так же чревато ошибками, как применение указателей в языке С. Найти такие ошибки иногда бывает очень трудно, особенно если нет безопасной версии STL.

В частности, для нормальной работы STL должны выполняться перечисленные ниже условия.

О Действительность итераторов. Например, перед использованием итераторы должны инициализироваться. Следует помнить, что итераторы могут стать недействительными вследствие побочных эффектов других операций. В частности, в векторах и деках это может произойти при вставке, удалении или перемещении элементов.

О Конечный итератор не связан с элементом контейнера, поэтому вызов операторов * и -> для него недопустим. В частности, это относится к возврапгае-мым значениям функций end() и rend() контейнерных классов.

О Действительность интервалов:

□ итераторы, определяющие интервал, должны огносигься к одному контейнеру;

□ второй итератор должен быть достижим в результате перебора элементов, начиная от первого.

О При использовании нескольких иттгервалов-источников второй и последующие интервалы должны содержать не меньше элементов, чем первый интервал.

О Количество элементов в приемном интервале должно быть достаточным для перезаписи; в противном случае необходимо использовать итераторы вставки.

Некоторые распространенные ошибки продемонстрированы в следующем примере:

stl/iterbugl.cpp #1nclude <iostreani> #include <vector> #include <algorithm> using namespace std:

int mainO {

vector<int> colli: Пустая коллекция vector<int> col 12: Пустая коллекция

/* ОШИБКА;

* - начало находится за концом интервала

vector<int>;:iterator pos = col 11.begin(): reverse (++pos. colli.endO):

Вставка элементов со значениями от 1 до 9 в со112 for (int i=l: i<=9: ++i) {



con2.push back (1):

/* ОШИБКА:

* - перезапись несуществующих элементов

сору {со112.beginO. соП2.епб{), Источник coin.beginO): Приемник

/* ОШИБКА:

* - перепутаны коллекции

. * - перепутаны beg1n{) и endC)

сору {colli.beginO. coll2.end{). Источник colli.endO): Приемник

Все указанные ошибки происходят не на стадии компиляции, а во время выполнения программы, поэтому они приводят к непредсказуемым последствиям.

Библиотека STL предоставляет массу возможностей для ошибок. Она вовсе ие обязана защищать вас от самого себя, поэтому желательно (по крайней мере, на время разработки программы) использовать безопасную версию STL. Первая безопасная версия STL была разработана Кеем Хорстманом (Сау Horstmann). К сожалению, многие поставщики предоставляют версию STL, основанную на исходном варианте кода, в котором обработка ошибок не предусмотрена. Впрочем, с>1туация постепенно улучшается. Современная безопасная версия STL распространяется бесплатно практически для всех платформ (http: www.stlport.org/).

Обработка исключений

Проверка логических ошибок в STL практически отсутствует, поэто.му сама библиотека STL почти не генерирует исключения, связанные с логикой. Фактически существует только одна функция, для которой в стандарте прямо указано на возможность возникновения исключения: речь идет о функции at() векторов и деков (проверяемой версии оператора индексирования). Во всех остальных случаях стандарт требует лишь стандартных исключений типа bad alioc при нехватке памяти или исключений, возникающих при пользовательских операциях.

Когда генерируются исключения и что при этом происходит с компонентами STL? В течение долгого времени, пока шел процесс стандартизации, строгих правил на этот счет не существовало. В сущности, любое исключение приводило к непредсказуемым последствиям. Даже уничтожение контейнера STL после того, как во время выполнения одной из поддерживаемых им операций произошло исключение, тоже приводило к непредсказуемым последствиям (например, аварийному завершению программы). Из-за этого библиотека STL оказывалась бесполезной там, где требовалось гарантированное четко определенное поведение, потому что не была предусмотрена даже возможность раскрутки стека.

За безопасной версией STL Кея Хорстмана обращайтесь по адресу http: www.horstmann. com/safestl.html.



1 ... 40 41 42 [ 43 ] 44 45 46 ... 239

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика