Реализация подсчета ссылок

Подсчет ссылок требует работы как со стороны инициатора класса, так и клиентов, использующих объекты этого класса. При реализации класса необходимо реализовать методы AddRef и Release в рамках интерфейса IUnknown. Эти два метода имеют следующие простые реализации:

  • AddRef увеличивает число внутренних ссылок объекта.
  • Сначала выпуск уменьшает внутреннее число ссылок объекта, а затем проверка, снизилось ли число ссылок до нуля. Если он имеется, это означает, что никто больше не использует объект, поэтому функция Release освобождает объект.

Распространенный подход реализации для большинства объектов заключается в наличии только одной реализации этих методов (наряду с QueryInterface), которая совместно используется для всех интерфейсов и поэтому счетчик ссылок, который применяется ко всему объекту. Однако, с точки зрения клиента, подсчет ссылок строго и четко представляет собой понятие указателя интерфейса, поэтому объекты, которые используют эту возможность, динамически создавая, уничтожая, загружая или выгрузив части их функциональных возможностей на основе существующих указателей интерфейса, могут быть реализованы. Это коллоквиально называемые интерфейсы сбоя.

Всякий раз, когда клиент вызывает метод (или функцию API), например QueryInterface, который возвращает новый указатель интерфейса, вызываемый метод отвечает за увеличение количества ссылок через возвращаемый указатель. Например, когда клиент сначала создает объект, он получает указатель интерфейса на объект, который с точки зрения клиента имеет количество ссылок. Если клиент вызывает AddRef в указателе интерфейса, число ссылок становится двумя. Клиент должен дважды вызвать выпуск в указателе интерфейса, чтобы удалить все его ссылки на объект.

Пример того, как счетчики ссылок строго зависят от указателя интерфейса, возникают, когда клиент вызывает QueryInterface на первом указателе для нового интерфейса или одного и того же интерфейса. В любом из этих случаев клиент должен вызывать выпуск один раз для каждого указателя. COM не требует, чтобы объект возвращал один и тот же указатель при запросе одного и того же интерфейса несколько раз. (Единственным исключением из этого является запрос на IUnknown, который идентифицирует объект com.) Это позволяет реализации объекта эффективно управлять ресурсами.

Безопасность потоков также является важной проблемой при реализации AddRef и Release. Дополнительные сведения см. в разделе "Процессы", "Потоки" и "Квартиры".

Управление временем существования объектов с помощью подсчета ссылок