безопасность прохождения наддува :: ссылка на shared_ptr - PullRequest
1 голос
/ 21 января 2011

мой вопрос, насколько отказоустойчивым является следующий фрагмент кода, который является частью моего менеджера ресурсов:

 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_ shared_ptr по ссылке фактически не является частью концепции shared_ptr, еслитолько использовать это в этой области, я мог столкнуться с проблемой?

Ответы [ 2 ]

4 голосов
/ 21 января 2011

Это использование безопасно, в том случае, если для shared_ptr<>, переданного через ссылку, будет уменьшен счет (если предполагается, что shared_ptr<>, возвращаемый из seeker->second->Copy(), не является shared_ptr<> для того же объекта), и поэтому объект, на который он будет указывать, может быть удален.

В частности, вы не создаете второй shared_ptr<> из необработанного указателя (что является ошибкой, потому что это приведет к созданию второго, не связанного shared_ptr<> с отдельным счетом и, следовательно, второго владельца объекта).

Будет ли ваша функция работать так, как вы хотите, зависит от того, что вы хотите.

1 голос
/ 22 января 2011

Полагаю, вы хотите сделать что-то вроде этого:

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 невозможно.

...