В последующем комментарии он немного прояснил вопрос
Это важный момент, который я пытался объяснить в первом разделе. Когда вы используете QSharedPointer, вы делитесь правами владения указателем. Класс контролирует и обрабатывает только указатель - все остальное (например, доступ к данным) находится за пределами его области видимости. Когда вы используете QSharedDataPointer, вы делитесь данными. И этот класс предназначен для неявного обмена: так что он может разделиться.
Попытка интерпретировать это:
Важно видеть, что «указатель» в данном случае не означает объект, хранящий адрес, но означает место хранения, в котором находится объект (сам адрес). Строго говоря, я думаю, вы должны сказать, что делитесь адресом. boost::shared_ptr
, таким образом, является умным указателем, разделяющим «указатель». boost::intrusive_ptr
или другой навязчивый умный указатель, кажется, тоже разделяет указатель, хотя знает что-то об объекте, на который указывает (что у него есть элемент подсчета ссылок или функции, увеличивающие / уменьшающие его).
Пример: если кто-то делит с вами черный ящик и он не знает, что находится в черном ящике, это похоже на совместное использование указателя (который представляет собой ящик), но не данных (что находится внутри ящика) ). На самом деле, вы даже не можете знать, что то, что находится внутри коробки, является разделяемым (что, если в коробке вообще ничего нет?). Интеллектуальные указатели представлены вами и другим парнем (и вы не разглашены, конечно), но адрес - это поле, а это .
Совместное использование данных означает, что интеллектуальный указатель знает достаточно данных, на которые он указывает, что он может изменить адрес, на который указывает (и это требует копирования данных и т. Д.). Таким образом, указатели теперь могут указывать на разные адреса. Так как адрес другой, адрес больше не передается. Вот что std::string
делает и в некоторых реализациях:
std::string a("foo"), b(a);
// a and b may point to the same storage by now.
std::cout << (void*)a.c_str(), (void*)b.c_str();
// but now, since you could modify data, they will
// be different
std::cout << (void*)&a[0], (void*)&b[0];
Совместное использование данных не обязательно означает, что вам представлен указатель. Вы можете использовать std::string
только с помощью a[0]
и cout << a;
и никогда не трогать ни одну из функций c_str()
. Тем не менее, обмен может продолжаться за сценой. То же самое происходит со многими классами Qt и классами других наборов инструментов виджетов, что называется неявное совместное использование (или копирование при записи ). Поэтому я думаю, что можно подвести итог так:
- Совместное использование указателя: мы всегда указываем на один и тот же адрес, когда копируем умный указатель, подразумевая, что мы разделяем значение указателя.
- Обмен данными. Мы можем указывать на разные адреса в разное время. Подразумевается, что мы знаем, как копировать данные с одного адреса на другой.
Итак, пытаясь классифицировать
boost::shared_ptr
, boost::intrusive_ptr
: поделиться указателем, а не данными.
QString
, QPen
, QSharedDataPointer
: Обмен данными, которые он содержит.
std::unique_ptr
, std::auto_ptr
(а также QScopedPointer
): ни общий указатель, ни данные.