Что такое неявное разделение? - PullRequest
13 голосов
/ 09 января 2011

Я создаю библиотеку игрового движка на C ++.Некоторое время назад я использовал Qt для создания приложения и был весьма очарован его использованием Implicit Sharing .Мне интересно, может ли кто-нибудь объяснить эту технику более подробно или предложить простой пример этого в действии.

1 Ответ

34 голосов
/ 09 января 2011

Ключевая идея неявного совместного использования, похоже, заключается в использовании более общего термина copy-on-write . Идея копирования при записи заключается в том, чтобы каждый объект служил оболочкой для указателя на фактическую реализацию. Каждый объект реализации отслеживает количество указателей на него. Всякий раз, когда выполняется операция над объектом-оболочкой, она просто перенаправляется в объект реализации, который выполняет фактическую работу.

Преимущество этого подхода состоит в том, что копирование и уничтожение этих объектов обходятся дешево. Чтобы сделать копию объекта, мы просто создаем новый экземпляр оболочки, устанавливаем его указатель так, чтобы он указывал на объект реализации, а затем увеличиваем количество указателей на объект (это иногда называется счетчик ссылок , кстати). Уничтожение аналогично - мы уменьшаем количество ссылок на единицу, а затем проверяем, указывает ли кто-либо еще на реализацию. Если нет, мы освобождаем его ресурсы. В противном случае мы ничего не делаем и просто предполагаем, что кто-то другой сделает уборку позже.

Проблема в этом подходе состоит в том, что это означает, что несколько разных объектов будут указывать на одну и ту же реализацию. Это означает, что если кто-то в конечном итоге вносит изменения в реализацию, каждый объект, ссылающийся на эту реализацию, увидит изменения - очень серьезная проблема. Чтобы исправить это, каждый раз, когда выполняется операция, которая может потенциально изменить реализацию, она проверяет, ссылаются ли какие-либо другие объекты также на реализацию, проверяя, является ли счетчик ссылок идентичным 1. Если никакие другие объекты не ссылаются на объект, то операция может продолжаться - нет возможности распространения изменений. Если существует хотя бы один другой объект, ссылающийся на данные, то оболочка сначала делает глубокую копию реализации для себя и изменяет свой указатель, указывая на новый объект. Теперь мы знаем, что не может быть никакого обмена, и изменения могут быть сделаны без хлопот.

Если вы хотите увидеть некоторые примеры этого в действии, взгляните на примеры лекций 15.0 и 16.0 из Стэнфордского вводного курса по программированию на C ++ . Он показывает, как спроектировать объект для хранения списка слов, используя эту технику.

Надеюсь, это поможет!

...