2015-12-17 4 views
3

Это теоретический вопрос. Когда проект основан на интеллектуальных указателях, так что практически все классы используют их для обертывания своих элементов указателя, неуместно ли передавать обычные указатели на функции члена/не члена? Я имею в виду, это правильно, чтобы иметь функции-члены, как:Умные указатели в функциях

void Function(SomeClass* pSomeClass); 

Или это всегда:

void Function(std::shared_ptr<SomeClass> pSomeClass); 

Я также побродить, если есть какие-либо важные последствия (кроме стандартного сопзЬ особенности) прохождения Const ссылка:

void Function(const std::shared_ptr<SomeClass>& pSomeClass) 

насчет ситуации, когда класс использует std::unique_ptr для защиты своих членов, а также, например, указатель на I Член ts используется в функции класса private? Должна ли она быть обернута? Или это следует считать ошибкой дизайна?

+0

Является ли функция делать что-либо с общим указателем? Или это просто разыгрывает его для использования сохраненного объекта? –

+3

Прежде всего, вы должны в большинстве случаев смотреть на новые умные указатели с точки зрения * собственности *, а не как своего рода указатель самоочистки. Тогда, если вы используете интеллектуальные указатели, вам нужно использовать их * везде * для этого указателя, просто создание 'shared_ptr' для перехода к функции не имеет смысла. Наконец, интеллектуальные указатели должны быть переданы (или возвращены) * по значению *, в противном случае их семантика действительно не работает. –

+0

@ Бенджамин Линдли; в большинстве случаев это просто разыгрывает его, чтобы использовать сохраненный объект. – DannyX

ответ

9

Если функции нужен только объект с заостренными объектами, и он всегда должен быть действительным объектом, а не нулевым, передать объект по ссылке (const или non-const, в зависимости от обычных правил).

Если функции нужен только объект с указателем или необязательно null, перейдите на необработанный указатель (на константу или не const, в соответствии с обычными правилами).

Если функции необходимо передать в собственность заостренного объекта, передайте shared_ptr по значению.

Если функция должна изменить shared_ptr дескриптор объекта (например, reset), передать shared_ptr по неконстантной ссылке.

Если функция должна получать доступ к информации о shared_ptr ручки (например, use_count), но не следует изменять shared_ptr, передать shared_ptr по константной ссылке.

5

Я думаю, что у Herb Sutter есть хорошие ответы. Существует GotW об использовании умных указателей и a more recent presentation, где он охватывает это. В новом C++ Core Guidelines содержится полный раздел об использовании интеллектуальных указателей.

В двух словах все это сходит "Take smart pointers as parameters only to explicitly express lifetime semantics". Если вы передадите умный указатель, это должно означать, что вы говорите/участвуете в собственности, либо разделяете, либо уникальны. Для параметров, не связанных с владением, текущие рекомендации являются исходными указателями или (const).