| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Пример контейнера для адаптера очередь |
| Автор: IvanoffAndrey 12.9.2007, 16:29 | ||||
| Буквально недавно здесь поднимался вопрос по поводу созданию массива ссылок и странной лабораторной. Я все выяснил: необходимо имитировать динамический массив ссылок (однако его свойства до сих пор для меня загадочны). Поскольку необходимо сделать массив динамический, то я написал контейнер список (для которого потом напишется адаптор) , и прекрасно знаю то лучше стандартного не получится, однако нельзя использовать STL на лабах (почему-то?). К этому списку написал что то подобное итератору с проверкой. Уважаемые друзья прошу оказать помощь: поругайте мой код, посоветуйте и развейте заблуждения. Вообще Итератор я писал первый раз и думаю это немножко не совсем итератор получился. Так же прошу оценить идею: Известно, что итератор на конец - итератор на следующий за последним элемент. Однако стандартные контейнеры позволяют туда писать вызывая тем самым ошибку. Что если сделать один конец в виде статической переменной шаблона и подкреплять на нее все концы списков. т.о. отпадает необходимость реализовывать итератор на константу. Пусть себе пишу в конец - ничего не произойдет. Данная концепция (наверное впервые (я никогда не видел) реализована ниже.) Код привожу ниже // Код файла LIST.h
//Код файла checked_list_iterator.h
|
| Автор: IvanoffAndrey 12.9.2007, 17:57 |
| Вот к примеру, как по завершению программы удалить память, на которую указывает статический указатель END шаблона . |
| Автор: IvanoffAndrey 12.9.2007, 18:38 |
| Точно, умный указатель. Сенькс за идею. Я хотел написать совместимый контейнер, но как я понимаю он должен использовать уже готовые стандартные шаблоны или наследовать что-то. Но все это уже относится к СТЛ. Может конечно я и ошибаюсь, тогда с удовольствием выслушал бы требования совместимости без использования СТЛ. |
| Автор: archimed7592 12.9.2007, 18:48 | ||
Programming languages - C++ ISO-IEC International Standard 14882 Second edition 2003-10-15 См. пункты 23.1 Container requirements 23.1.1 Sequences 24.1 Iterator requirements |
| Автор: IvanoffAndrey 14.9.2007, 16:57 |
| TO archimed7592. А мне кажется что умный указатель все таки не особо хорошее решение. Сегодня мне подсказали другое: Заводим счетчик объектов. И если объекты после удаления последнего отсутствуют, то удаляем память. Этот способ имеет много преимуществ - одно из которых - экономия памяти, что важно если объекты помещаемые в контейнер очень большие. |
| Автор: archimed7592 14.9.2007, 17:17 | ||||
И теряем в производительности, ибо, если раньше всё срабатывало автоматически(по завершению программы срабатывали деструкторы статических объектов - никакого оверхэда), то теперь на каждый конструктор/деструктор будем иметь оверхэд в виде подсчёта кол-ва объектов. Нет уж. Давай, выкладывай все "преимущества"
Поподробнее, для меня тупого: в каком месте экономия и как помещаемые в контейнер объекты связаны со статическим членом вообще и с auto_ptr в частности? |
| Автор: IvanoffAndrey 14.9.2007, 17:54 | ||
Объясняю...Не надо ерничать. В данном коде написан шаблон класса CLIST. Который содержит в себе в виде статического поля указатель на КЛАСС NODE. Объект класса NODE может содержать в поле VALUE к примеру какую нибудь большую структуру, ну скажем текстовый файл (каким - нибудь образом представленный). END необходим нам лишь на то время пока существую объекты типа CLIST и не необходим иначе. Поэтому я попытался отконтролировать это. К тому же я не утверждал идеальность этого подхода! Я всего лишь интересовался твоим мнением по этому поводу. |
| Автор: archimed7592 14.9.2007, 18:15 | ||||
Угу, понял. Просто не совсем понял разницу. Ты имеешь ввиду, что лишний node будет иметь место только когда есть объекты-списки и, в ином случае будет чуть больше памяти свободной. Ну, возможно это что-то даст. Я бы на твоём месте задумался бы как вообще избавиться от этого END. К примеру можно использовать NULL в качестве END. Чем не вариант? Обязательно нужен существующий объект с адресом? По-моему достаточно всего лишь адреса, а 0 - универсальный адрес, который помимо всего прочего не может указывать ни на один объект.
Моё мнение: если уж делать, то посредством static weak_ptr + member shared_ptr - в этом случае нигде не успустишь подсчёт ссылок - он будет производиться автоматически. |
| Автор: IvanoffAndrey 14.9.2007, 23:06 |
| С NULL мне тама по смыслу не годится. А вот как думаешь?, должен ли контейнер автоматически (при своей смерти) вызывать деструкторы всех итераторов которые на него созданы или нет? А то провел эксперимент: Если вручную деструктором убить любой контейнер STL библиотеки, то все итераторы на него целехоньки а это как то странно. Может что-то типа наблюдателя поставить за итераторами, у меня есть идя как это реализовать: При инициализации итератора с проверкой контейнером, вызывается функция в контейнере, которая добаляет создаваемый итератор в какойто специальный массивчик , а потом когда контейнер уничтожится, в деструкторе удалим и массивчик, что вызовет цепочку деструкторов итераторов прикрепленных к этому контейнеру. Эта технология вроде носит какое то умно название, только вот вспомнить не могу. Ведь если уж делать итератор с проверкой так действительно проверять все и исключать ошибки (а не лукавить как Страуструп проверяя в примере только на конец и начало). |
| Автор: archimed7592 15.9.2007, 05:53 | ||||||||
Почему, если не секрет?
Упаси господи. В отладочной версии он может указать итераторам, что они инвалидированы. В "боевой" версии - произвольное поведение. Лучше(для релиза) писать итератор так, будто контейнер жив и всё используется как полагается.
Ок, смотри:
Лучше их инвалидировать, а инвалидированный итератор должен выбрасывать исключение при любой попытке его неправильно использовать.
Нет, ты не понимаешь. Checked-итераторы нужны в отладочной версии. Они проверяют все необходимые предусловия, постусловия и инварианты, т.о. позволяя выявить ошибку ещё во время "тестовых запусков"(при том условии, что боевая версия итераторов могла бы спокойно отработать и ошибку бы просто не заметили бы) и с некоторой вероятностью гарантирует выполнение контракта со Стандартом т.о. повышая портабельность программы(на одном компиляторе итератор сделан как-то по особому, что ошибка не будет проявляться, а, на всех других платформах программа будет вываливаться в кору). |