Имейте в виду, что блокировка очень дорога, и это происходит каждый раз, когда вы перемещаете объекты между умными указателями - даже когда объект в данный момент принадлежит одному потоку (библиотека умных указателей этого не знает).
Учитывая это, здесь может применяться эмпирическое правило (я рад, что меня поправили!)
Если к вам применимо следующее:
- У вас есть сложные структуры данных, для которых было бы сложно написать деструкторы (или там, где семантика значений в стиле STL была бы неприемлемой по своему замыслу), поэтому вам нужны умные указатели, чтобы сделать это за вас, и
- Вы используете несколько потоков, совместно использующих эти объекты, и
- Вы заботитесь о производительности и правильности
... тогда фактическая сборка мусора может быть лучшим выбором. Хотя у GC плохая репутация по производительности, все относительно. Я считаю, что это очень выгодно по сравнению с блокировкой умных указателей. Это была важная часть того, почему команда CLR выбрала настоящий GC вместо того, чтобы использовать подсчет ссылок. См. эту статью , в частности это абсолютное сравнение того, что означает справочное присвоение, если у вас идет подсчет:
без пересчета:
a = b;
подсчет ссылок:
if (a != null)
if (InterlockedDecrement(ref a.m_ref) == 0)
a.FinalRelease();
if (b != null)
InterlockedIncrement(ref b.m_ref);
a = b;