Программирование >>  Инициализация объектов класса, структура 

1 ... 75 76 77 [ 78 ] 79 80 81 ... 395


ilist::ilist( const ilist &rhs )

ilist item *pt = rhs. at front;

while ( pt

insert end( pt->value() );

pt = pt->next();

реализация конструктора, использующая функцию insert end() :

Оператор присваивания должен сначала вызвать remove all(), а затем с помощью insert end() вставить все элементы второго списка. Поскольку эта операция

void ilist::insert all ( const ilist &rhs )

ilist item *pt = rhs. at front;

while ( pt

insert end( pt->value() );

pt = pt->next();

повторяется в обеих функциях, вынесем ее в отдельную функцию insert all() :

inline ilist::ilist( const ilist &rhs )

: at front( 0 ), at end( 0 ) { insert all ( rhs ); }

inline ilist&

ilist::operator=( const ilist &rhs ) { remove all(); insert all( rhs ); return *this;

после чего копирующий конструктор и оператор присваивания можно реализовать так:

Теперь осталось обеспечить пользователя возможностью путешествовать но списку, например с помощью доступа к члену at front:

ilist item *ilist::front() { return at front(); }

После этого можно применить ilist item::next() , как мы делали в функциях-членах:

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



ilist item *pt = mylist.front();

while ( pt ) {

do something( pt->value () ); pt = pt->next();

Хотя это решает проблему, лучше поступить иначе: реализовать общую концепцию прохода по элементам контейнера. В данном разделе м1 расскажем об использовании

for ( ilist item *iter = mylist.init iter(); iter;

iter = mylist.next iter() )

цикла такого вида:

do something( iter->value() );

(В разделе 2.8 м1 уже касались понятия итератора. В главах 6 и 12 будут рассмотрены итераторы для имеющихся в стандартной библиотеке контейнерных типов и обобщенных алгоритмов.)

Наш итератор представляет собой несколько больше, чем просто указатель. Он должен уметь запоминать текущий элемент, возвращать следующий и определять, когда все элементы кончились. По умолчанию итератор инициализируется значением at front, однако пользователь может задать в качестве начального любой элемент списка. next iter() возвращает следующий элемент или 0, если элементов больше нет. Для

class ilist { public:

...

init iter( ilist item *it = 0 ); private:

...

ilist item * current; реализации пришлось ввести дополнительный член класса:

inline ilist item* ilist::init iter( i1ist item *it ) {

return current = it ? it : at front; init iter() выглядит так:

next iter() перемещает указатель current на следующий элемент и возвращает его адрес, если элементы не кончились. В противном случае он возвращает 0 и устанавливает current в 0. Его реализацию можно представить следующим образом:



inline ilist item*

ilist::

next iter()

ilist item *next = current

return next;

? current = current->next() : current;

Если элемент, на котор1й указывает current, удален, могут возникнуть проблем:. Их преодолевают модификацией кода функций remove() и remove front() : они должны проверять значение current. Если он указывает на удаляемый элемент, функции изменят его так, чтобы он адресовал следующий элемент либо был равен 0, когда удаляем1й элемент - последний в списке или список стал пустым. Модифицированная

inline void ilist::remove front()

if ( at front ) {

ilist item *ptr = at front; at front = at front->next();

current не доен указывать на удаленн элемент if ( current == ptr )

current = at front;

bump down size();

delete ptr;

remove front() выглядит так:

while ( plist ) { if ( plist->va

if ( plist->value() == value )

prev->next( plist->next() );

if ( current == plist )

Вот модифицированный фрагмент кода remove() :

current = prev->next();

Что произойдет, если элемент будет вставлен перед тем, на который указывает current? Значение current не изменяется. Пользователь должен начать проход но списку с помощью вызова init iter() , чтобы новый элемент попал в число перебираемых. При инициализации списка другим и при присваивании значение current не копируется, а сбрасывается в 0.

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



1 ... 75 76 77 [ 78 ] 79 80 81 ... 395

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