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_IREFOBJECT_H 00015 #define CNTM_IREFOBJECT_H 00016 #include <Cntm/RefCount/RefPtr.h> 00017 00018 namespace Cntm 00019 { 00020 00021 namespace SpecUtils 00022 { 00023 template < typename T > class RefObjectPtrProxy; 00024 template < typename T > class RefObjectPtrPtrProxy; 00025 } 00026 00027 /** 00028 * Интерфейс для объекта, подсчитывающего ссылки на себя. Используется объектом для декларации возможности подсчитывать ссылки. 00029 * 00030 * При использовании объектов, подсчитывающих ссылки (наследующих данный интерфейс), следует учитывать следующее. Все управление подсчетом ссылок осуществляется через ссылочные указатели - RefPtr при их инициализации, присвоении, уничтожении (см. класс RefPtr). Все обращения к объекту, подсчитывающему ссылки, должны производится через ссылочные указатели. Пока выполняется метод объекта, должен иметься ссылочный указатель на этот объект (это требование следует учитывать при разработке многопоточных систем или систем с обратными вызовами). 00031 * 00032 * При создании объекта его счетчик ссылок устанавливается в 0. При инициализации ссылочного указателя ссылкой на объект или другим ссылочным указателем производится увеличение кол-ва ссылок на объект. При потере ссылки при разрушении ссылочного указателя или присвоении ему нового значения счетчик ссылок на старый объект уменьшается. 00033 * 00034 * При достижении счетчиком ссылок 0 объект переводится в т.н. удаляемое состояние, в котором он может находиться до своего физического удаления. Если наряду с сылочными указателями используются и обычные указатели, то при присвоении ссылочному указателю обычного указателя на объект, который находится в удаляемом состоянии, ссылочный указатель принудительно будет установлен в NULL (все это не относится к случаю, когда ссылочному указателю присваивается значение другого ссылочного указателя, т.к. объект по определению не может находится в удаляемом состоянии при наличии хотя бы одного ссылочного указателя). Поэтому перед использованием ссылочного указателя после присвоения ему обычного указателя его следует проверять на NULL. Из этого правила существуют 2 очевидных исключения: 00035 * - проверять на NULL не надо после инициализации указателем на только что созданный объект, возвращаемый оператором new; 00036 * - при использовании this внутри методов самого объекта, т.к. при выполнении метода, вызванного клиентом, объект не может находиться в удаляемом состоянии (это не относится к деструктору). 00037 * 00038 * Создавать объекты с подсчетом ссылок рекомендуется в динамической памяти. В статической памяти или в стеке тоже возможно, однако при этом нельзя использовать ссылочные указатели, т.к. это приведет к вызову опертора delete не в динамической памяти. 00039 * 00040 * Внимание! Когда объект создается в динамической памяти, необходимо присвоить результат оператора new какому-либо указателю (с использованием конструктора, принимающего обычный указатель, или операции NewPointer), даже если объект не будет использоваться. В противном случае объект никогда не будет удален автоматически. 00041 * 00042 * Наследующие классы не могут сами реализовывать данный интерфейс. Для реализации они должны наследовать RefBase, RefBaseEx или AggregatedBase. 00043 * 00044 * Для удобства использования наследующие данный интерфейс классы должны объявлять вложенный тип Ptr как ссылочный указатель на этот класс: 00045 * \code 00046 * class MyClass : public Cntm::RefBase 00047 * { 00048 * public: 00049 * typedef Cntm::RefPtr<MyClass> Ptr; 00050 * ..... 00051 * }; 00052 * .... 00053 * MyClass::Ptr p1 = new MyClass; 00054 * \endcode 00055 * 00056 * Реализации интерфейса поддерживают многопоточность. 00057 * @author Овсеевич Р. 00058 * \ingroup RefCount 00059 */ 00060 class IRefObject 00061 { 00062 public: 00063 00064 typedef RefPtr < IRefObject > Ptr; 00065 00066 private: 00067 00068 friend class RefBase; 00069 friend class AggregatedBase; 00070 template < typename T > friend class SpecUtils::RefObjectPtrProxy; 00071 template < typename T > friend class SpecUtils::RefObjectPtrPtrProxy; 00072 00073 /** 00074 * Увеличить кол-во ссылок. Возвращает true, если объект не находится в удаляемом состоянии и кол-во ссылок увеличено, иначе возвращается false. 00075 */ 00076 virtual bool IncRefCount() = 0; 00077 00078 /** 00079 * Уменьшить кол-во ссылок. Если счетчик ссылок достиг 0, то возвращается true, иначе возвращается false. 00080 */ 00081 virtual bool DecRefCount() = 0; 00082 00083 /** 00084 * Сообщить объекту, что он может быть удален. 00085 */ 00086 virtual void DeleteInstance() = 0; 00087 }; 00088 00089 } 00090 00091 // Следует средства для void* включать вместе со средствами для IRefObject* 00092 #include <Cntm/RefCount/Internal/RefNoneOpsImpl.h> 00093 #include <Cntm/RefCount/Internal/GenericRefNonePtrImpl.h> 00094 00095 // Включение средств для IRefObject* промзводится после полного определения IRefObject 00096 #include <Cntm/RefCount/Internal/RefObjectOpsImpl.h> 00097 #include <Cntm/RefCount/Internal/GenericRefObjectPtrImpl.h> 00098 00099 #endif //CNTM_IREFOBJECT_H
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |