00001 /* 00002 * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события 00003 * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru 00004 * _______________________________________________________________________________ 00005 * Разрешено свободное использование, копирование, распространение, изменение 00006 * (изменение сведений об авторских правах запрещено). Запрещена продажа и 00007 * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об 00008 * авторских правах на программу (или сведениях о программе, об авторах, 00009 * использованных средствах разработки и т.д.) должна быть указана информация 00010 * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е. 00011 * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора. 00012 */ 00013 00014 #ifndef CNTM_NOREFPTRREGISTEREX_H 00015 #define CNTM_NOREFPTRREGISTEREX_H 00016 #include <Cntm/RefCount/Internal/NoRefPtrStorage.h> 00017 #include <Cntm/RefCount/RefPtr.h> 00018 #include <Cntm/Containers/RegisterEx.h> 00019 00020 namespace Cntm 00021 { 00022 00023 /** 00024 * Это шаблонный класс перечня, хранящий не ссылочные (обычные) указатели на объекты, однако принимающий и перечисляющий ссылочные указатели. Когда происходит сохранение значения в перечне, ссылочный указатель преобразуется в обычный, когда происходит перечисление эл-тов - наоборот - из обычного в ссылочный. При этом следует учитывать, что если ссылочный объект находится в удаляемом состоянии, то в результате преобразования обычного указателя к ссылочному, последний примет значение NULL, однако перечислитель автоматически пропускает указатели на NULL, т.о. текущее значение перечислителя никогда не будет равняться NULL. В качестве параметра шаблона указывается тип объекта. 00025 * 00026 * Данный класс может использоваться, когда требуется такая регистрация ссылочных объектов, которая не приводила бы к хранению ссылок на объекты. В этом случае при создании объект регистрирует себя в перечне, а перед уничтожением - уничтожает регистрацию (например, в деструкторе). В какой бы момент не происходило перечисление, если на объект есть ссылки, то будет возвращен ссылочный указатель на этот объект, если объект находится в удаляемом состоянии, но он еще не изъял свой указатель из перечня, то при перечислении он будет пропущен, если же объект изъял свой указатель из перечня, то он уже не будет перечислен. 00027 * 00028 * Отличие данного класса от Cntm::NoRefPtrRegister состоит в том, что он является объектом с подсчетом ссылок, а эл-ты перечня и перечислители используют ссылочные указатели. Т.о. имеется гарантия того, что перечень будет существовать, пока существует хоть один перечислитель или эл-т, зарегистрировавший свое значение в данном перечне. 00029 * 00030 * Класс обеспечивает многопоточность. 00031 * @author Овсеевич Р. 00032 * \ingroup Containers 00033 */ 00034 template < typename T > 00035 class NoRefPtrRegisterEx : public RegisterEx < RefPtr < T >, SpecUtils::NoRefPtrStorage < T > > 00036 { 00037 public: 00038 00039 typedef RefPtr < NoRefPtrRegisterEx > Ptr; 00040 00041 typedef RegisterEx < RefPtr < T >, SpecUtils::NoRefPtrStorage < T > > RegisterType; 00042 00043 /** 00044 * Класс перечислителя. Наследует класс перечислителя перечня. 00045 * 00046 * Переопределяет метод Next() и операторы ->() и ++(). 00047 * \ingroup Containers 00048 */ 00049 class Enumerator: public RegisterEx < RefPtr < T >, SpecUtils::NoRefPtrStorage < T > > ::Enumerator 00050 { 00051 public: 00052 00053 /** 00054 * Оператор позволяет получить доступ к членам объекта, на который указывает текущее значение перечислителя. 00055 * 00056 * Следует помнить, что если при перечислении метод Next() вернул true, то гарантируется, что текущее значение перечислителя не содержит NULL. 00057 */ 00058 const RefPtr < T > & operator-> () const { return Enumerator::Current(); } 00059 00060 /** 00061 * Перейти к следующему эл-ту. Вызывает функцию Next(). См. функцию Next(). 00062 */ 00063 Enumerator& operator++ () 00064 { 00065 Next(); 00066 return *this; 00067 } 00068 00069 /** 00070 * Практически во всем совпадает с функцией Next() предка (Register::Enumerator::Next()) за исключением того, что ссылочные указатели, содержащие NULL, автоматически пропускаются при перечислении, т.о. текущее значение никогда не будет содержать указатель на NULL. 00071 */ 00072 bool Next() 00073 { 00074 while (RegisterType::Enumerator::Next()) 00075 if (Enumerator::Current()) return true; 00076 return false; 00077 } 00078 00079 protected: 00080 00081 friend class NoRefPtrRegisterEx; 00082 00083 /** 00084 * Конструктор. Используется перечнем для инициализации перечислителя. 00085 */ 00086 Enumerator(const NoRefPtrRegisterEx::Ptr& Reg, bool DynamicExpanded): 00087 RegisterType::Enumerator(Reg, DynamicExpanded) {} 00088 }; 00089 00090 /** 00091 * Получить объект перечислителя для доступа к эл-там. 00092 * @param DynamicExpanded - true (значение по умолчанию) - перечислитель будет перечислять эл-ты, добавленные в перечень после создания перечислителя, false - перечислитель будет переслять только те эл-ты, которые были в перечне на момент создания перечислителя (удаленные эл-ты перечислитель не перечисляет в любом случае). 00093 */ 00094 Enumerator GetEnumerator(bool DynamicExpanded = true) const 00095 { 00096 return Enumerator(this, DynamicExpanded); 00097 } 00098 }; 00099 00100 } 00101 00102 #endif //CNTM_NOREFPTRREGISTEREX_H
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |