У меня иногда есть shared_ptr<T> &
, который я хочу привести к shared_ptr<T const> &
, но как я могу сделать это, не искажая счет использования?
Ты не. Само понятие неверно. Посмотрите, что происходит с голым указателем T*
и const T*
. Когда вы разыгрываете T*
в const T*
, у вас теперь есть два указателя . У вас нет двух ссылок на один и тот же указатель; у вас есть два указателя.
Почему это должно отличаться для умных указателей? У вас есть два указателя: один на T
, а другой на const T
. Они оба являются владельцами одного и того же объекта, поэтому вы используете два из них. Следовательно, use_count
должно быть 2, а не 1.
Ваша проблема - ваша попытка перегрузить значение use_count
, используя его функциональность для каких-то других целей. Короче говоря: вы делаете это неправильно.
Ваше описание того, что вы делаете с shared_ptr
s, кто use_count
один, это ... страшно . Вы в основном говорите, что некоторые функции используют один из своих аргументов, который вызывающий абонент явно использует (поскольку вызывающий, очевидно, все еще использует его). И вызывающая сторона не знает, какая из них была заявлена (если таковая имеется), поэтому вызывающая сторона не знает , не подозревая , в каком состоянии находятся аргументы после функции. Изменение аргументов для таких операций обычно не очень хорошая идея.
Кроме того, то, что вы делаете, может работать, только если вы передадите shared_ptr<T>
по ссылке, что само по себе не очень хорошая идея (как и обычные указатели, умные указатели почти всегда должны приниматься по значению).
Короче говоря, вы берете очень часто используемый объект с четко определенными идиомами и семантикой, а затем требует, чтобы он использовался таким образом, чтобы они почти никогда не использовались, со специализированной семантикой, которая работает против того, как все на самом деле их используют. Это не очень хорошая вещь.
Вы фактически создали концепцию совместимого указателя, разделяемого указателя, который может находиться в трех состояниях использования: пусто, используется лицом, предоставившим его только вам, и, таким образом, вы можете украсть его и использовать более чем одним человеком, поэтому вы не можете иметь его. Это не семантика, которую shared_ptr
существует для поддержки. Поэтому вы должны написать свой собственный умный указатель, который обеспечивает эту семантику гораздо более естественным способом.
Что-то, что распознает разницу между тем, сколько у вас экземпляров указателя и сколько у вас реальных пользователей. Таким образом, вы можете передать его по значению правильно, но у вас есть некоторый способ сказать, что вы в настоящее время используете его и не хотите, чтобы одна из этих других функций требовала его. Он может использовать shared_ptr
внутри, но должен обеспечивать свою семантику.