IRefObject.h

См. документацию.
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

SourceForge.net Logo
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой  doxygen 1.5.3