Насколько осторожно следует обрабатывать std :: shared_ptr? - PullRequest
1 голос
/ 02 февраля 2012

Я был несколько удивлен, обнаружив, что std::shared_ptr не обеспечивает защиты (например, генерирует исключение) от ситуаций, когда его указанный объект каким-либо образом удален. Я полагаю, что это из соображений производительности; если предположить, что shared_ptr выполняет свою работу, объект, на который указывает shared_ptr, никогда не должен был быть удален, так что было бы глупо тратить время на постоянную проверку.

Я знаю, что могу явно проверить, действителен ли shared_ptr, но если shared_ptr "выполняет свою работу" по поддержанию времени жизни объекта, было бы излишним явно проверять каждый раз, когда я касаюсь shared_ptr.

Итак, мой вопрос: насколько я должен быть осторожен в свете этого? Есть ли «практическое правило» относительно того, как часто, или когда я должен проверять shared_ptr?

Мой лучший вывод на данный момент будет имитировать Java: всякий раз, когда вам передают ссылку на объект в Java, который вы не создали, вы должны проверить его на null. Будет ли это хорошая политика для shared_ptr?

Ответы [ 3 ]

6 голосов
/ 02 февраля 2012

Как и любой другой указатель, проверьте его перед использованием, если у вас есть основания подозревать, что он может обернуть нулевой указатель.

shared_ptr действительно помогает управлять временем жизни объекта, на который он указывает, но это совершенно отдельная задача от решения, указывает ли на объект.

4 голосов
/ 02 февраля 2012

std::shared_ptr не обеспечивает защиты (например, генерирует исключение) от ситуаций, когда его объект, на который указывает указатель, каким-то образом становится нулевым.

Язык C ++не распознает такую ​​вещь, как объект NULL.

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

Если у вас есть только умные указатели, такие как std::shared_ptr, указывающие на объект, вам никогда не придется удалять объект, и он не будет удален преждевременно.

2 голосов
/ 02 февраля 2012

На практике я не использую нулевые указатели (или нулевые умные указатели) для передачи состояния, потому что это усложняет, нужно ли и когда нужно проверять наличие нулевых и сложных == ошибок. Поэтому я никогда не проверяю ноль, я просто использую указатель, зная, что это хорошо.

Единственный раз, когда я использую нулевые указатели, это для отложенной инициализации членов (иногда указатель создается после некоторого чтения некоторых данных, поэтому я не могу инициализировать его в списке инициализации членов).

...