Что такое неявное разделение?
Я создаю библиотеку игрового движка на C++. Некоторое время назад я использовал Qt для создания приложения и был довольно увлечен его использованием Implicit Sharing. Мне интересно, может ли кто-нибудь объяснить эту технику более подробно или предложить простой пример этого в действии.
1 ответ
Ключевая идея неявного совместного использования, похоже, заключается в использовании более распространенного термина " копирование при записи". Идея копирования при записи заключается в том, чтобы каждый объект служил оболочкой для указателя на фактическую реализацию. Каждый объект реализации отслеживает количество указателей на него. Всякий раз, когда выполняется операция над объектом-оболочкой, она просто перенаправляется в объект реализации, который выполняет фактическую работу.
Преимущество такого подхода заключается в том, что копирование и уничтожение этих объектов обходятся дешево. Чтобы сделать копию объекта, мы просто создаем новый экземпляр обертки, устанавливаем его указатель так, чтобы он указывал на объект реализации, а затем увеличиваем количество указателей на объект (это иногда называют счетчиком ссылок, Кстати). Уничтожение аналогично - мы уменьшаем количество ссылок на единицу, а затем проверяем, указывает ли кто-либо еще на реализацию. Если нет, мы освобождаем его ресурсы. В противном случае мы ничего не делаем и просто предполагаем, что кто-то другой сделает уборку позже.
Проблема в этом подходе состоит в том, что это означает, что несколько разных объектов будут указывать на одну и ту же реализацию. Это означает, что если кто-то в конечном итоге вносит изменения в реализацию, каждый объект, ссылающийся на эту реализацию, увидит эти изменения - очень серьезная проблема. Чтобы исправить это, каждый раз, когда выполняется операция, которая может потенциально изменить реализацию, она проверяет, ссылаются ли какие-либо другие объекты также на реализацию, проверяя, является ли счетчик ссылок идентичным 1. Если никакие другие объекты не ссылаются на объект, то операция может продолжаться - нет возможности распространения изменений. Если есть хотя бы один другой объект, ссылающийся на данные, то оболочка сначала делает глубокую копию реализации для себя и изменяет свой указатель, чтобы указать на новый объект. Теперь мы знаем, что не может быть никакого обмена, и изменения могут быть сделаны без хлопот.
Если вы хотите увидеть некоторые примеры этого в действии, взгляните на примеры лекций 15.0 и 16.0 из вводного курса программирования C++ для Стэнфорда. Он показывает, как спроектировать объект для хранения списка слов, используя эту технику.
Надеюсь это поможет!