Я хочу передати спільний покажчик функції. Чи можете ви мені в цьому допомогти?
Звичайно, я можу вам із цим допомогти. Я припускаю, що ви дещо розумієте семантику власності в C ++. Це правда?
Так, мені досить зручно з цим предметом.
Добре.
Гаразд, я можу думати лише про дві причини shared_ptr
аргументувати:
- Функція хоче поділити право власності на об’єкт;
- Функція виконує певну операцію, яка працює спеціально для
shared_ptr
s.
Який із вас цікавить?
Я шукаю загальної відповіді, тому насправді мене цікавить і те, і інше. Однак мені цікаво, що ви маєте на увазі у випадку №2.
Прикладами таких функцій є std::static_pointer_cast
користувацькі порівняльники або предикати. Наприклад, якщо вам потрібно знайти всі унікальні shared_ptr з вектора, вам потрібен такий предикат.
Ах, коли функції насправді потрібно маніпулювати самим розумним вказівником.
Точно так.
У такому випадку, я думаю, нам слід пройти шляхом посилання.
Так. І якщо це не змінює вказівник, ви хочете передати посилання const. Не потрібно копіювати, оскільки вам не потрібно ділитися правом власності. Це інший сценарій.
Добре, зрозумів. Поговоримо про інший сценарій.
Той, де ви ділитесь власністю? В порядку. Як ви ділитеся власністю shared_ptr
?
Скопіювавши його.
Тоді функції потрібно буде зробити копію a shared_ptr
, правильно?
Очевидно. Тож я передаю його посиланням на const та копіюю до локальної змінної?
Ні, це песимізація. Якщо його передано за посиланням, функції не залишиться іншого вибору, як зробити копію вручну. Якщо воно передається за значенням, компілятор вибере найкращий вибір між копією та переміщенням та виконає його автоматично. Отже, передайте значення.
Гарна думка. Я повинен пам’ятати, що стаття " Хочете швидкість? Пропустіть цінність " частіше.
Зачекайте, а якщо функція зберігає shared_ptr
, наприклад, змінну-член? Чи не буде це зробити надлишкову копію?
Функція може просто перемістити shared_ptr
аргумент у своє сховище. Переміщення a shared_ptr
є дешевим, оскільки це не змінює жодного підрахунку посилань.
Ах, гарна ідея.
Але я думаю про третій сценарій: що робити, якщо ви не хочете маніпулювати цим shared_ptr
, ані ділитися власністю?
У такому випадку shared_ptr
це абсолютно не має значення для функції. Якщо ви хочете маніпулювати пуантом, візьміть пуанте та дозвольте абонентам вибрати, яку семантику власності вони хочуть.
І чи слід брати пуанте за посиланням чи за значенням?
Застосовуються звичайні правила. Розумні вказівники нічого не змінюють.
Передайте значення, якщо я збираюся скопіювати, передайте посилання, якщо хочу уникнути копіювання.
Правильно.
Хм Я думаю, ви забули ще один сценарій. Що робити, якщо я хочу поділитися власністю, але лише залежно від певної умови?
Ах, цікавий крайній випадок. Я не очікую, що це трапляється часто. Але коли це відбувається, ви можете або передати значення, і ігнорувати копію, якщо вона вам не потрібна, або передати посилання та зробити копію, якщо вам це потрібно.
Я ризикую однією надмірною копією в першому варіанті, а втрачу потенційний хід у другому. Чи не можу я з'їсти торт і його теж взяти?
Якщо ви потрапили в ситуацію, коли це насправді важливо, ви можете забезпечити дві перевантаження, одну з яких бере посилання const lvalue, а іншу - посилання rvalue. Один копіює, інший рухається. Ще один варіант - ідеальний шаблон функції переадресації.
Я думаю, що це охоплює всі можливі сценарії. Дуже дякую.
const std::shared_ptr<myClass>& arg1