     Например, выражение iterator.Current() возвращает текущий элемент 
контейнера Queue — первого объекта при первом обращении. Если контейнер пуст, 
итератор вернет нулевой указатель (или нулевую ссылку, если контейнер 
запоминает сами объекты). 
    При использовании итератора в выражениях имейте в виду, что он возвращает 
целое значение. Это возможно благодаря тому, что в классах-итераторах 
перегружается оператор преобразования к типу int(). Таким образом, когда объект 
итератора используется в выражениях, оперирующих целыми значениями, в 
программе вызывается оператор int() для преобразования объекта к этому 
значению. Если это значение равно нулю (ложь), значит итератор завершил 
сканирование данных в контейнере. 
    С помощью функций и значений итератора можно "прогуливаться по очереди", 
отображая объекты контейнера в том порядке, в котором они запоминались:	

    while (iterator != 0) {	// Использовать перегруженный оператор int()       
       cout « «iterater.Current() « nedl;	// Извлечь текущий объект               
       iterator++;                                              // Переместить итератор к следующему объекту 

    Во всех итераторах реализован оператор инкремента ++ (как постфиксный, так 
и префиксный). Как продемонстрировано в предыдущем фрагменте, вы можете 
пользоваться выражениями iterator++ (или ++iterator) для перемещения объекта 
итератора к следующему объекту в контейнере. Оператор ++ возвращает объект 
того же типа, что и контейнер, — этим фактом вы можете воспользоваться для 
эффективной реализации циклов. Установим итератор в начальное положение с 
помощью обращения к его функции Restart() и объявим указатель на строку р 
следующим образом:	

    iterator.Restart();      // Установить итератор на первый объект
    string *p;                                    // Объявить указатель на строку 

    Теперь можно написать следующий цикл while (или что-нибудь в этом роде) 
для перемещения по контейнеру: 

    while (р = iterator++)   // Извлечь текущий объект и продвинуть итератор 
    cout << *р << endl;      // Отобразить объект,  адресуемый р 

    В управляющем выражении цикла while указателю р присваивается адрес 
текущего строкового объекта, кроме того итератор перемещается к следующему 
объекту. По достижении последнего объекта управляющее выражение принимает 
нулевое значение и цикл завершается. В простом операторе вывода в поток 
отображается каждый строковый объект. 
    Если вы скомпилируете предыдущий код, возможно, компилятор выдаст вам 
предупреждение "possibly incorrect assignment" ("возможно неверное 
присваивание"), поскольку оператор = в данном контексте распознается как 
возможная ошибка в написании оператора сравнения ==. Тем не менее, наличие 
единственного знака = в данном случае корректно, поскольку мы хотим присвоить 
значение, возвращаемое итератором, указателю р. Если вас беспокоит присутствие 
этого предупреждения, замените предыдущий код следующим фрагментом, он 
полностью эквивалентен приведенному выше, хотя и труднее читается: 

    while ( ( р = iterator++ ) != 0 )     
         cout « «р « endl; 

    Все итераторы имеют, по крайней мере, один конструктор, функцию Restart() и 
перегруженные операторы int() и ++. Некоторые итераторы снабжаются также 
дополнительными специальными функциями. Например, в итераторах массивов 
перегружается функция Restart с двумя параметрами: 

    void   Restart(unsigned start,   unsigned stop); 

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

    Принадлежность объектов 

    Запомнить объект в контейнере совсем не так легко, как положить конфетку 
на блюдечко. С конфеткой все просто. Вы ее положили, затем откусили кусочек — 
и все прекрасно. С контейнерными объектами больше хлопот (и меньше риска 
растолстеть). Вам необходимо знать, имеете ли вы дело с динамическими 
объектами, созданными с помощью оператора new, или же с объектами, которые 
существуют временно в стеке, а может быть с глобальными, размещающимися в 
сегменте данных. Вам также должно быть известно, "подлинный" объект или это 
только его "внебрачная" копия. Объектам класса могут потребоваться 
деструкторы, в особенности, если они ссылаются на другие динамические 
структуры. В подобных случаях вы должны обеспечить вызов деструктора и 
своевременное уничтожение объектов. 
    В результате этих хлопот возникает вопрос, должны ли объекты принадлежать 
контейнеру, в котором они запоминаются? В целом, если объекты принадлежат 
контейнеру, он должен их уничтожать автоматически, когда объекты удаляются из 
контейнера. Если же объекты не принадлежат контейнеру, ответственность за их 
уничтожение в случае необходимости лежит на вас.	


    Глава 16. Библиотека шаблонов классов Borland	433 
