лучшая практика при возврате интеллектуальных указателей

$result = array_merge_recursive($first, $second);

может быть полезно, когда у вас есть массивы с массивами внутри.

31
задан Rolle 10 June 2009 в 11:28
поделиться

9 ответов

Нет "правильного" пути. Это действительно зависит от контекста.

Вы можете внутренне обрабатывать память с помощью интеллектуального указателя и извне давать ссылки или необработанные указатели. В конце концов, пользователю вашего интерфейса не нужно знать, как вы управляете памятью внутри. В синхронном контексте это безопасно и эффективно. В асинхронном контексте существует множество ловушек.

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

В качестве последнего примечания, в C ++ не злоупотребляйте динамически выделяемыми объектами. Есть много случаев, когда вы не t нужен указатель и может работать со ссылками и константными ссылками. Это безопаснее и снижает нагрузку на распределитель памяти.

23
ответ дан 27 November 2019 в 22:17
поделиться

Я следую следующим рекомендациям по передаче аргументов указателей функциям и возвращению указателей:

boost::shared_ptr

API и клиент разделяют владение этим объектом. Однако вы должны быть осторожны, чтобы избежать циклических ссылок с shared_ptr , если объекты представляют собой какой-то граф. По этой причине я стараюсь ограничить использование shared_ptr .

boost::weak_ptr / raw pointer

API владеет этим объектом, вам разрешено делиться им, пока он действителен. Если есть шанс, что клиент будет жить дольше, чем api, я использую weak_ptr.

std::auto_ptr

API создает объект, но клиент владеет объектом. Это гарантирует, что возвращаемый код является безопасным в отношении исключений и четко указывает, что право собственности передается.

boost::scoped_ptr

Для указателей на объекты, хранящиеся в стеке или как переменные-члены класса. Сначала я пытаюсь использовать scoped_ptr .

8
ответ дан 27 November 2019 в 22:17
поделиться

На мой взгляд, в C ++ вы всегда должны оправдывать использование незащищенного указателя.

Может быть много веских причин: потребность в очень высокой производительности, для очень низкого использования памяти, для работы с устаревшими библиотеками, из-за некоторых проблем с базовой структурой данных, которую хранит указатель. Но [динамически выделяемые] указатели в некоторой степени «зло», поскольку вам нужно освободить память на каждом возможном пути выполнения, и вы почти наверняка забудете об одном.

3
ответ дан 27 November 2019 в 22:17
поделиться

Я бы не стал помещать исходные указатели в векторы.

Если они используют auto_ptr или boost :: scoped_ptr, они не могут использовать (или возвращать) что-либо, кроме необработанных указателей. Думаю, это могло бы объяснить их способ кодирования.

0
ответ дан 27 November 2019 в 22:17
поделиться

зависит от ваших целей.

слепой возврат smart ptr к внутренним данным может быть не очень хорошей идеей (что очень важно для задачи, которую вы пытаетесь решить) - вам может быть лучше просто предложить некоторые doX () и doY (), которые используют указатель внутри.

с другой стороны, при возврате smart ptr вы также должны учитывать, что вы не будете создавать взаимных циклических ссылок, когда объекты в конечном итоге не могут уничтожить друг друга (weak_ptr может быть лучшим вариантом в этом случае).

в противном случае, как уже упоминалось выше, следует учитывать все аспекты производительности / устаревшего кода / времени жизни.

0
ответ дан 27 November 2019 в 22:17
поделиться

Это зависит от значения указателя.

При возврате shared_pointer вы синтаксически говорите: «Вы будете разделять владение этим объектом», так что, если исходный объект-контейнер умирает до того, как вы отпустите указатель, этот объект

Возврат необработанного указателя говорит: «Вы знаете об этом объекте, но не владеете им». Это способ передать контроль,

11
ответ дан 27 November 2019 в 22:17
поделиться

Я обычно возвращаю "владеющие" / "уникальные" интеллектуальные указатели с фабрик или аналогичные, чтобы прояснить, кто отвечает за очистку.

Этот пример https: // ideone .com / qJnzva показывает, как вернуть std :: unique_ptr , который будет удален, когда область видимости переменной, которой вызывающий объект присваивает значение, выходит за пределы области.

Хотя это правда что интеллектуальный указатель удаляет свой собственный указатель, время жизни переменной, содержащей интеллектуальный указатель, на 100% контролируется вызывающей стороной, поэтому вызывающая сторона решает, когда будет удален указатель. Однако, поскольку это «уникальный» и «владеющий» интеллектуальный указатель, ни один другой клиент не может контролировать время жизни.

7
ответ дан 27 November 2019 в 22:17
поделиться

const boost :: shared_ptr & getInternal () {return m_internal;}

Это позволяет избежать копирования.

Иногда вам нужно вернуть ссылку, например:

  • Y & оператор * () {return * m_internal; }
  • const Y & оператор * () const {return * m_internal; }

Это тоже хорошо, только если ссылка будет использована и немедленно удалена. То же самое и с необработанным указателем. Также возможен возврат weak_ptr.

Четверка хороша в зависимости от целей. Этот вопрос требует более широкого обсуждения.

-1
ответ дан 27 November 2019 в 22:17
поделиться

Я бы никогда не вернул необработанный указатель, вместо этого я бы вернул weak_ptr, чтобы сообщить пользователю указателя, что он не контролирует ресурс.

Если вы вернете a weak_ptr weak_ptr очень маловероятно, что в приложении будут висячие указатели.

Если есть проблема с производительностью, я бы вернул ссылку на объект и метод hasValidXObject.

4
ответ дан 27 November 2019 в 22:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: