Я хочу передать общий указатель на функцию. Вы можете мне с этим помочь?
Конечно, я могу вам помочь. Я предполагаю, что вы имеете некоторое представление о семантике владения в C ++. Это правда?
Да, я достаточно доволен этой темой.
Хороший.
Хорошо, я могу придумать только две причины, чтобы shared_ptr
поспорить:
- Функция хочет разделить владение объектом;
- Функция выполняет некоторую операцию, которая работает конкретно с
shared_ptr
s.
Что вас интересует?
Я ищу общий ответ, поэтому меня действительно интересуют оба варианта. Мне любопытно, что вы имеете в виду в случае № 2.
Примеры таких функций включают std::static_pointer_cast
настраиваемые компараторы или предикаты. Например, если вам нужно найти все уникальные shared_ptr из вектора, вам понадобится такой предикат.
Ах, когда функции действительно нужно манипулировать самим интеллектуальным указателем.
В яблочко.
В таком случае, я думаю, нам следует перейти по ссылке.
Да. И если он не меняет указатель, вы хотите передать по константной ссылке. Нет необходимости копировать, так как вам не нужно делить владение. Это другой сценарий.
Хорошо понял. Поговорим о другом сценарии.
Тот, где вы разделяете собственность? ОК. Как вы делите собственность с shared_ptr
?
Копируя это.
Тогда функции нужно будет сделать копию shared_ptr
, правильно?
Очевидно. Итак, я передаю его по ссылке на const и копирую в локальную переменную?
Нет, это пессимизация. Если он передается по ссылке, у функции не будет другого выбора, кроме как сделать копию вручную. Если он передается по значению, компилятор выберет лучший выбор между копией и перемещением и выполнит его автоматически. Итак, переходите по значению.
Хорошая точка зрения. Я должен чаще вспоминать эту статью « Хотите скорости? Передайте по значению ».
Подождите, а что, если функция хранит shared_ptr
, например, в переменной-члене? Разве это не будет дублирующей копией?
Функция может просто переместить shared_ptr
аргумент в свое хранилище. Перемещение a shared_ptr
обходится дешево, потому что не меняет счетчик ссылок.
Ах, хорошая идея.
Но я думаю о третьем сценарии: что, если вы не хотите shared_ptr
ни манипулировать собственностью , ни делиться ею?
В этом случае shared_ptr
совершенно не имеет отношения к функции. Если вы хотите манипулировать указателем, возьмите указатель и позвольте вызывающим абонентам выбрать, какую семантику владения они хотят.
И брать указателя по ссылке или по стоимости?
Применяются обычные правила. Умные указатели ничего не меняют.
Передайте по значению, если я собираюсь копировать, передайте по ссылке, если я хочу избежать копирования.
Правильно.
Хм. Думаю, вы забыли еще один сценарий. Что, если я хочу разделить собственность, но только при определенных условиях?
Ах, интересный крайний случай. Я не ожидаю, что это будет происходить часто. Но когда это происходит, вы можете либо передать по значению и игнорировать копию, если она вам не нужна, либо передать по ссылке и сделать копию, если она вам нужна.
Я рискую одной дублирующей копией в первом варианте и теряю потенциальный ход во втором. Разве я не могу съесть торт и тоже?
Если вы находитесь в ситуации, когда это действительно важно, вы можете предоставить две перегрузки: одна принимает ссылку на const lvalue, а другая - ссылку на rvalue. Один копирует, другой двигается. Другой вариант - шаблон функции идеальной пересылки.
Я думаю, это охватывает все возможные сценарии. Большое спасибо.
const std::shared_ptr<myClass>& arg1