Суть управления временем жизни объектов с помощью подсчета ссылок заключается в следующем. Объект обладает таким свойством, как кол-во ссылок на него. После создания объекта кол-во ссылок на него устанавливается в 1, т.к. создатель получает ссылку на объект. Если создатель передает ссылку на созданный объект еще кому-то, то счетчик ссылок объекта следует увеличить на 1. Когда использование объекта завершено, то следует уменьшить кол-во ссылок на 1 и больше не использовать ссылку. Когда счетчик ссылок достигает 0, это означает, что пользователей данного объекта не осталось и он должен запустить процедуру своего уничтожения.
Базовые классы подсчета ссылок
Для декларации объектов, которые подсчитывают ссылки на себя (такие объекты будем называть ссылочными), библиотека предоставляет интерфейс Cntm::IRefObject. Данный интерфейс определяет правила управления подсчетом ссылок со стороны объекта. Правила подсчета ссылок приведены в описании интерфейса Cntm::IRefObject. Библиотека предоставляет базовые классы, реализующие интерфейс Cntm::IRefObject: Cntm::RefBase для простых случаев и Cntm::RefBaseEx для более сложных. Класс, который должен обеспечивать подсчет ссылок должен наследовать Cntm::RefBase или Cntm::RefBaseEx.
Сложный объект может содержать встроенные объекты, время жизни которых совпадает с временем жизни сложного объекта, т.е. за создание и уничтожение которых отвечает сложный объект. В этом случае сложный объект называют агрегатом, а встроенные объекты - агрегируемыми объектами. В некоторых случаях требуется использовать ссылки на агрегированные объекты. Т.к. время жизни агрегируемого объекта определяется агрегатом, то при увеличении кол-ва ссылок на агрегируемый объект следует увеличивать ссылки на агрегат. Аналогичная переадресация должна выполняться и при уменьшении кол-ва ссылок. Т.о. агрегат будет существовать, пока есть ссылки на него или на его агрегированные объекты. Данная политика выпоняется классом Cntm::AggregatedBase, который реализует интерфейс Cntm::IRefObject. Если объект предназначен для агрегирования, то его класс должен наследовать Cntm::AggregatedBase. Класс Cntm::AggregatedBaseпросто перенаправляет вызовы методов увеличения и уменьшения ссылок агрегату, который передан ему при создании.
Управление увеличением и уменьшением счетчика ссылок со стороны пользователей объекта автоматизировано с помощью ссылочных указателей. Сылочные указатели представлены классом Cntm::RefPtr<T>. Это шаблонный класс, где T - класс, на объекты которого будет указывать ссылочный указатель. При чтении он ведет себя практически как обычный указатель T*, т.е. для него определены операторы ->, *, bool, ! и ==. Но при создании и записи этот класс выполняет действия по изменению кол-ва ссылок. Для данного класса существуют 2 вида конструкторов и операторов присваивания: принимающие указатель на объект - T* и принимающие ссылочный указатель. Конструкторы и операторы присваивания увеличивают кол-во ссылок на присваиваемый объект. Деструктор и операторы присваивания уменьшают кол-во ссылок на текущий объект.
Если при инстанциации шаблона Cntm::RefPtr<T> тип T не является классом, подсчитывающим ссылки, т.е. не является Cntm::IRefObject или его наследником,то Cntm::RefPtr ведет себя как обычный указатель, т.е. не выполняет ни каких действий по изменению кол-ва ссылок и, соответственно не управляет уничтожением объекта.
Назначение обобщенных ссылочных указателей такое же, что и у обычных - управление подсчетом ссылок. Однако между ними имеется большое отличие - обобщенные указатели не являются шаблонами, т.е. не зависят от типа объекта, на который указывают. Через обобщенный указатель нельзя использовать для доступа к членам класса, т.к. он хранит указатель на void*. Обобщенный указатель следует использовать тогда, когда требуется управление подсчетом ссылок, не нужно обращаться к членам класса и желательно отказаться от шаблонов. При присвоении не ссылочного объекта (унаследованного не от Cntm::IRefObject) ни каких действий по изменению кол-ва ссылок не выполняется. Подробности в описании класса Cntm::GenericRefPtr.
В некоторых случаях требуется обеспечить потенциальную возможность управлять подсчетом ссылок. Это реализуется с помощью класса Cntm::GenericNoRefPtr, который не изменяет кол-во ссылок сам по себе, но м.б. присвоен обобщенному ссылочному указателю Cntm::GenericRefPtr.
Кроме обычных обобщенных указателей имеются обобщенные указатели на методы объектов Cntm::GenericMethodRefPtr и Cntm::GenericMethodNoRefPtr. Они соединяют обобщенные указатели на объект с адресом метода этого объекта. Их поведение полностью аналогично Cntm::GenericRefPtr и Cntm::GenericNoRefPtr соответственно.
Классы | |
class | Cntm::AggregatedBase |
Базовый класс для объектов, являющихся составными частями агрегата (агрегированных объектов). Подробнее... | |
class | Cntm::GenericMethodNoRefPtr< SignatureT > |
Класс указателя на метод объекта. Подробнее... | |
class | Cntm::GenericMethodRefPtr< SignatureT > |
Класс указателя на метод объекта. Подробнее... | |
class | Cntm::GenericNoRefPtr |
Класс обобщенного не ссылочного указателя. Подробнее... | |
class | Cntm::GenericRefPtr |
Обобщенные ссылочные указатели это нешаблонные, нетипизированные указатели (указатели на void*), обладающие способностью управлять подсчетом ссылок на указываемый объект. Подробнее... | |
class | Cntm::IRefObject |
Интерфейс для объекта, подсчитывающего ссылки на себя. Подробнее... | |
class | Cntm::RefBase |
Основная реализация подсчета ссылок. Подробнее... | |
class | Cntm::RefBaseEx |
Более сложная реализация подсчета ссылок. Подробнее... | |
class | Cntm::RefObjectUsedException |
При уничтожении объекта с подсчетом ссылок выяснилось, что на него еще имеются ссылки, созданные в деструкторе. Подробнее... | |
class | Cntm::RefPtr< T > |
Специальный ссылочный указатель для автоматизации подсчета ссылок на объекты. Подробнее... |
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |