Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
сомнения меня гложут, как правильно делать? раньше, если я возвращал какую-то переменную класса геттером, я делал так: Код: plaintext 1. теперь, если у меня в классе переменная идёт, как shared_ptr<T>, то я и должен возвращать ровно shared_ptr<T>, чтобы создалась ещё одна копия, и счётчик таким образом увеличился на 1. Код: plaintext 1. если же я сделаю так: Код: plaintext 1. то это выстрел в ногу, так как счётчик не изменится. вроде так. Если я выше не прав, то поправьте. если прав, то дальше меня тревожит то, что я в геттере возвращаю копию. Т.е. создаётся ещё один объект, зовётся конструктор и всё такое. Как сложить эти две вещи вместе, возвращать ссылку на объект(это быстро) и авто-контролировать счётчик (это безопасно)? Как вообще правильно работать в данном случае с shared_ptr<T> снаружи классов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 09:27 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMb, ты просто забыл включить мозг. ;) Если ты объявил переменную типа shared_ptr<T> на стеке внутри метода, то после выхода из метода счетчик останется неизменным, так как предыдущий экземпляр shared_ptr<T> будет уничтожен деструктором и счетчик уменьшен на ту же единицу. Если ты объявил "shared_ptr<T>" на стеке, то вернуть его как "shared_ptr<T>&" ты не можешь, так как, опять же, его экземпляр будет разрушен после выхода из области видимости. Возвращать его как "shared_ptr<T>&" ты можешь, например, если объявил этот указатель как "static shared_ptr<T>&". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 09:46 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
rdb_devCEMb, ты просто забыл включить мозг. ;). он пишет про член - где вы увидели возврат ссылки на локальную переменную? 2CEMb - геттер у тебя ведь простой без логики? зачем он у тебя лежит в cpp? помести его в h и он заинлайнится оптимизатором. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 09:59 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
PPAон пишет про член - где вы увидели возврат ссылки на локальную переменную?Здесь подразумевается возврат экземпляра класса-указателя на член типа "T" экземпляра класса "A", а не то, что "shared_ptr<T>" объявлен как член класса. Здесь "T", это тип члена класса "A", а "shared_ptr<T>", это подобие "T*" или "T&", но если два последних, это простые типы указателя и ссылки на "T", то "shared_ptr<T>", это класс указателя (некая реализация сборки мусора). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 10:27 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 10:32 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMb, передача по значению - есть передача по значению. И в случае с shared_ptr она может быть достаточно тяжёлой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 10:37 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
YesSqlпередача по значению - есть передача по значению. И в случае с shared_ptr она может быть достаточно тяжёлой. Во-первых, современные компиляторы делают copy elimination, что сильно облегчает процесс. Во-вторых, современная парадигма С++ игнорирует вопросы быстродействия в пользу легко читаемого кода. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 10:47 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
rdb_devCEMb, ты просто забыл включить мозг. ;)я не могу включить то, чего нет, поэтому и пришёл с вопросом. PPAзачем он у тебя лежит в cpp?а как по коду ты понял, где он лежит? rdb_devЗдесь подразумевается возврат экземпляра класса-указателя на член типа "T" экземпляра класса "A", а не то, что "shared_ptr<T>" объявлен как член класса.ненене, именно объявлен как shared_ptr<T>, но если это пагубная практика, то расскажите, как правильно. Имхо, неправильно отдавать кому-то shared_ptr<T> если сам объект shared_ptr<T> не является. Грубо говоря, управление памятью должно быть единообразно. Иначе, как вариант: если после геттера объект класса А будет уничтожен, код, получивший shared_ptr<T> не узнает об этом и помешать этому не сможет. Заново. Код: plaintext 1. 2. 3. 4. Get() создаёт копию объекта shared_ptr<T>, который инициализируется указателем на t_, т.е. с копирование адреса t_ у нас тут проблем нет, но вот с вызовом конструктора shared_ptr<T> - как бы накладные расходы, да? Учение говорит, что возвращать надо ссылки(или указатели, когда нельзя ссылки), иначе будет неявно зваться конструктор. Но (тот самый вопрос), если мы сделаем так: Код: plaintext 1. то получим ссылку на t_, копирование указателя пройдёт быстро, никаких лишних вызовов и кода (как велит учение), но, опять же, если объект класса А будет уничтожен после геттера, геттер узнает об этом(хоть с трудом, но можно), но помешать этому не сможет. Вопрос в том: как теперь, в связи с shared_ptr надо отдавать переменные класса. Ну или в обратную сторону: как описывать входящие параметры типа shared_ptr<T> в функциях. Если как ссылки - быстро и ненадёжно, если как объекты, то надёжно и небыстро. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 10:50 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
YesSqlпередача по значению - есть передача по значению. И в случае с shared_ptr она может быть достаточно тяжёлой.Эээ тяжёлой, но не достаточно тяжёлой. Это просто вызов конструктора shared_ptr<T> и передача ему указателя на объект. Т.е. тяжело, но не сильно. Но передача по ссылке - всё равно легче. Dimitry SibiryakovВо-первых, современные компиляторы делают copy elimination, что сильно облегчает процесс.А, блин, точно, там оптимизация по возвращаемому значению же... я забыл про это :( Ну, т.е. мой вариант Код: plaintext 1. - абсолютно верный? :) Dimitry SibiryakovВо-вторых, современная парадигма С++ игнорирует вопросы быстродействия в пользу легко читаемого кода.но при этом авторы сделали очень много, чтобы увеличить это самое быстродействие. Ладно, не будем вдаваться в детали, а то сщас начнётся... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 10:55 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbYesSqlпередача по значению - есть передача по значению. И в случае с shared_ptr она может быть достаточно тяжёлой.Эээ тяжёлой, но не достаточно тяжёлой. Это просто вызов конструктора shared_ptr<T> и передача ему указателя на объект. Т.е. тяжело, но не сильно. Но передача по ссылке - всё равно легче. Все зависит от задачи. Это не "просто вызов конструктора" это атомик или мютекс в зависимости от имплементации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 11:06 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
OoCcВсе зависит от задачи. Это не "просто вызов конструктора" это атомик или мютекс в зависимости от имплементации.Ну ок. Так как тогда правильно возвращать значения и передавать параметры в функции? Или зависит от типа? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 11:18 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbOoCcВсе зависит от задачи. Это не "просто вызов конструктора" это атомик или мютекс в зависимости от имплементации.Ну ок. Так как тогда правильно возвращать значения и передавать параметры в функции? Или зависит от типа? Прелесть С++ в том что все зависит от задачи и ее дизайна. С++ может быть Java-ой а может быть и C с-классами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 11:35 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbИмхо, неправильно отдавать кому-то shared_ptr<T> если сам объект shared_ptr<T> не является. Грубо говоря, управление памятью должно быть единообразно. Иначе, как вариант: если после геттера объект класса А будет уничтожен, код, получивший shared_ptr<T> не узнает об этом и помешать этому не сможет.Если ты самостоятельно разрушаешь объект, то shared_ptr об этом, по-любому, никак не узнает. Если ты используешь shared_ptr<T>, ни о каком самостоятельном разрушении экземпляра "T", на который ссылается экземпляр "shared_ptr<T>" не может быть и речи. При использовании "умных указателей", без накладных расходов не обойтись, но можно сократить количество созданий и разрушений shared_ptr при передаче его в качестве результата. Возвращай из геттера как "shared_ptr<T>&" - по ссылке и не парься! Так как в коде ты всё равно будешь делать что-то типа: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 11:47 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
Ошибся в написании: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 12:03 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
OoCcПрелесть С++ в том что все зависит от задачи и ее дизайна.так мне-то в вышеприведённом коде, без atomic и mustex, как лучше делать? rdb_devВозвращай из геттера как "shared_ptr<T>&" - по ссылке и не парься!Нет, так неправильно. Пример: Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 12:11 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbOoCcПрелесть С++ в том что все зависит от задачи и ее дизайна.так мне-то в вышеприведённом коде, без atomic и mustex, как лучше делать? rdb_devВозвращай из геттера как "shared_ptr<T>&" - по ссылке и не парься!Нет, так неправильно. Пример: Код: plaintext 1. 2. 3. С таким дизайном тебе больше подходит Java-подобная парадигма С++ 20569314 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 12:27 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbrdb_devВозвращай из геттера как "shared_ptr<T>&" - по ссылке и не парься!Нет, так неправильно. Пример: Код: plaintext 1. 2. 3. Что именно неправильно? Если экземпляр "T" не является инкапсулированным в "A", то удаление экземпляра "A" приведет к удалению "умной ссылки", а не самого экземпляра "T", при условии, что где-либо существует еще одна валидная ссылка "shared_ptr<T>" на данный экземпляр "T". Пример: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 13:11 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
Чтоб было понятнее, перепишем пример так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 13:21 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
точнее так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 13:26 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
Можно возвращать ссылку на смартуказатель. А если вызывающему коду надо продлить время жизни объекта по этой ссылке, то там надо положить эту ссылку в копию смартуказателя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2017, 14:37 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
Если тебе не нужно делать очень часто так: Код: plaintext 1. 2. тогда возвращай по значению shared_ptr<T> A::Get() {...} Возвращение shared_ptr по ссылке несет больше потенциальных проблем, чем по значению. Но в некоторых случаях может быть быстрее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2017, 22:56 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
rdb_dev Код: plaintext 1. интересный момент. Я имел ввиду: Код: plaintext 1. И тогда delete a; уничтожит и t_ тоже (по идее должно, не проверял) Или, иными словами:Anatoly MoskovskyА если вызывающему коду надо продлить время жизни объекта по этой ссылке, то там надо положить эту ссылку в копию смартуказателя.Т.е. получается, что если мы возвращаем ссылку на shared_ptr, мы оставляем на совести вызывающего следить за тем, жив a в момент вызова Get() или нет. Ну ок, мне этот вариант больше нравится, спасибо всем :) Пойду переписывать код... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2017, 05:38 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbТ.е. получается, что если мы возвращаем ссылку на shared_ptr, мы оставляем на совести вызывающего следить за тем, жив a в момент вызова Get() или нет. Ну ок, мне этот вариант больше нравится, спасибо всем :) Пойду переписывать код...Ну да! Представь, что тебе, по какой-то причине, понадобилось вызвать a->Get() вхолостую - без присваивания значения в вызывающей программе, чтобы инициализировать объект "T" заранее. При этом, если "shared_ptr<T>" будет возвращаться по значению, то объект будет создан дважды - в куче и на стеке (конструктором копии). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2017, 09:29 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbЯ имел ввиду: Код: plaintext 1. И тогда delete a; уничтожит и t_ тоже (по идее должно, не проверял)Обязано! Так как "shared_ptr<T>" является инкапсулируемым, он будет разрушен при разрушении экземпляра "A" автоматически сгенерированным для этой цели кодом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2017, 10:18 |
|
||
|
shared_ptr как возвращаемый результат
|
|||
|---|---|---|---|
|
#18+
CEMbТ.е. получается, что если мы возвращаем ссылку на shared_ptr, мы оставляем на совести вызывающего следить за тем, жив a в момент вызова Get() или нет. Ну ок, мне этот вариант больше нравится, спасибо всем :) Пойду переписывать код... Если программа многопоточная, то возврат ссылки (а не копии) создает точку, когда объект может быть уничтожен между возвратом и присвоением его в копию. Поэтому, если объект используется в нескольких потоках, то ссылки использовать нельзя (кроме случаев когда вы другими способами гарантируете время жизни объекта). Создание же копии смартуказателя это атомарная операция и гарантирует что другой поток не уничтожит объект. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2017, 13:52 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=39472848&tid=2018140]: |
0ms |
get settings: |
9ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
170ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
| others: | 280ms |
| total: | 556ms |

| 0 / 0 |
