if ( ptr-value() == value )
break;
ptr = ptr-next();
}
return ptr;
}
Функцию find() можно использовать следующим образом:
ilist_item *ptr = mylist.find( 8 );
mylist.insert( ptr, some_value );
или в более компактной записи:
mylist.insert( mylist.find( 8 ), some_value );
Перед тем как тестировать операции вставки элементов, нам нужно написать функцию display(), которая поможет нам при отладке. Алгоритм display() достаточно прост: печатаем все элементы, с первого до последнего. Можете ли вы сказать, где в данной реализации ошибка?
// не работает правильно!
for ( ilist_item *iter = _at_front; // начнем с первого
iter != _at_end; // пока не последний
++iter ) // возьмем следующий
cout iter-value() ' ';
// теперь напечатаем последний
cout iter-value();
Список – это не массив, его элементы не занимают непрерывную область памяти. Инкремент итератора
++iter;
вовсе не сдвигает его на следующий элемент списка. Вместо этого он указывает на место в памяти, непосредственно следующее за данным элементом, а там может быть все что угодно. Для изменения значения итератора нужно воспользоваться членом _next объекта ilist_item:
iter = iter-_next;
Мы инкапсулировали доступ к членам ilist_item набором встраиваемых функций. Определение класса ilist_item теперь выглядит так:
class ilist_item {
public:
ilist_item( int value, ilist_item *item_to_link_to = 0 );
int value() { return _value; }
iilst_item* next() { return _next; }
void next( ilist_item *link ) { _next = link; }
void value( int new_value ) { _value = new_value; }
private:
int _value;
ilist_item *_next;
};
Вот определение функции display(), использующее последнюю реализацию класса ilist_item:
#include iostream
class ilist {
public:
void display( ostream os = cout );
// ...
};
void ilist::
display( ostream os )
{
os "\n( " _size " )( ";
ilist_item *ptr = _at_front;
while ( ptr ) {
os ptr-value() " ";
ptr = ptr-next();
}
os ")\n";
}
Тестовую программу для нашего класса ilist в его текущей реализации можно представить таким образом:
#include iostream
#include "ilist.h"
int main()
{
ilist mylist;
for ( int ix = 0; ix 10; ++ix ) {
mylist.insert_front( ix );
mylist.insert_end( ix );
}
cout
"Ok: после insert_front() и insert_end()\n";
mylist.display();
ilist_item *it = mylist.find( 8 );
cout "\n"
"Ищем значение 8: нашли?"
( it ? " да!\n" : " нет!\n" );
mylist.insert( it, 1024 );
cout "\n"
"Вставка элемента 1024 после 8\n";
mylist.display();
int elem_cnt = mylist.remove( 8 );
cout "\n"
"Удалено " elem_cnt
" элемент(ов) со значением 8\n";
mylist.display();
cout "\n" "Удален первый элемент\n";
mylist.remove_front(); mylist.display();
cout "\n" "Удалены все элементы\n";
mylist.remove_all(); mylist.display();
}
Результат работы программы:
Ok: после insert_front() и insert_end()
(20)( 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 )
Ищем значение 8: нашли? да!
Вставка элемента 1024 после 8
( 21 )( 9 8 1024 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 )
Удалено 2 элемент(ов) со значением 8
( 19 )( 9 1024 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 9 )
Удален первый элемент
( 18 )( 1024 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 9 )
Удалены все элементы
( 0 )( )
Помимо вставки элементов, необходима возможность их удаления. Мы реализуем три таких операции: