Если у вас есть умные указатели не из `std`, следуйте базовому паттерну из `std`
Причина
Правила из следующего раздела работают и для других видов сторонних и пользовательских умных указателей и очень полезны для диагностики распространённых ошибок с умными указателями, вызывающих проблемы с производительностью и корректностью. Эти правила должны работать для всех умных указателей, которые вы используете.
Любой тип (включая первичный шаблон или специализацию), перегружающий унарные * и ->, считается умным указателем:
- Если он копируемый, он распознаётся как
shared_ptrс подсчётом ссылок. - Если он некопируемый, он распознаётся как уникальный
unique_ptr.
Пример (плохой)
// использование intrusive_ptr из Boost
#include <boost/intrusive_ptr.hpp>
void f(boost::intrusive_ptr<widget> p) // ошибка согласно правилу 'sharedptrparam'
{
p->foo();
}
// использование CComPtr от Microsoft
#include <atlbase.h>
void f(CComPtr<widget> p) // ошибка согласно правилу 'sharedptrparam'
{
p->foo();
}
Оба случая — ошибка согласно рекомендации sharedptrparam: p является Shared_pointer, однако здесь его свойство разделённости не используется, и передача по значению является молчаливым ухудшением производительности; эти функции должны принимать умный указатель только если им нужно участвовать в управлении временем жизни widget. В противном случае они должны принимать widget*, если возможен nullptr. Или, в идеале, функция должна принимать widget&. Эти умные указатели соответствуют концепции Shared_pointer, поэтому правила применяются к ним автоматически и выявляют это распространённое ухудшение производительности.