Безопасность прохождения Boost :: shared_ptr Ссылка
-
15-10-2019 - |
Вопрос
Мой вопрос: насколько безопасный-это следующий фрагмент кода, который является частью моего менеджера по ресурсам:
bool Load(std::string name, boost::shared_ptr<Asset::Model>& newModel)
{
std::map<std::string, boost::scoped_ptr<Asset::Model> >::const_iterator seeker;
seeker = models.find(name);
if (seeker == models.end())
return false;
newModel = seeker->second->Copy(); // Copy returns a boost::shared_ptr<Asset::Model>
return true;
}
private:
std::map< std::string, boost::scoped_ptr<Asset::Model> > models;
Поскольку прохождение Boost's shared_ptr по ссылке на самом деле не является частью концепции shared_ptr, если я использую его только в этой области, могу ли я столкнуться с проблемами?
Решение
Это использование безопасно, что бы ни было shared_ptr<>
прошел через ссылку, будет уменьшено возрождение (при условии, что shared_ptr<>
вернулся из seeker->second->Copy()
не shared_ptr<>
к тому же объекту) и, следовательно, объект, на который он будет указывать, может быть удален.
В частности, вы не создаете секунду shared_ptr<>
Из необработанного указателя (которая является ошибкой, потому что он создаст второй, не связанный shared_ptr<>
с отдельным возрождением и, следовательно, вторым владельцем объекта).
Предоставляет ли ваша функция желаемое поведение, зависит от того, чего вы хотите.
Другие советы
Я думаю, ты хочешь сделать что -то вроде этого:
boost::shared_ptr<Asset::Model> ptr;
if(Load("stuff", ptr))
{
doSomething with ptr
}
В этом случае все будет в порядке.
Однако вам не нужно использовать ссылку здесь. Просто верните а shared_ptr
и установите его на 0, если элемент не найден:
boost::shared_ptr<Asset::Model> Load(std::string name)
{
std::map<std::string, boost::scoped_ptr<Asset::Model> >::const_iterator seeker;
boost::shared_ptr<Asset::Model> retPtr;
seeker = models.find(name);
if (seeker == models.end())
return retPtr;
retPtr = seeker->second->Copy(); // Copy returns a boost::shared_ptr<Asset::Model>
return retPtr;
}
Однако я заметил, что вы используете scoped_ptr
В стандартном контейнере - который AFAIK невозможно.