безопасное использование std :: tr1 :: shared_ptr - PullRequest
2 голосов
/ 08 апреля 2011

Этот подход небезопасен?

#include <tr1/memory>

Foo * createFoo()
{
  return new Foo(5);
}

int main()
{
  std::tr1::shared_ptr<Foo> bar(create());

  return 0;
}

Или для createFoo было бы предпочтительнее вернуть shared_ptr<Foo> объект?

Ответы [ 2 ]

3 голосов
/ 08 апреля 2011

Ваш пример безопасен так, как вы его написали.Однако вы можете сделать его еще более герметичным, если ваш фабричный метод createFoo() возвращает автоматический указатель вместо необработанного указателя.Таким образом, вы гарантированно, что не будет никаких утечек.

Итак, вы получите:

#include <memory>
#include <tr1/memory>

std::auto_ptr<Foo> createFoo()
{
  return std::auto_ptr<Foo>(new Foo(5));
}

int main()
{
  std::tr1::shared_ptr<Foo> bar(createFoo());

  return 0;
}

Конечно, также возможно, чтобы ваш фабричный метод возвратил shared_ptr, но это может рассматриваться как избыточное, так как возвращаемый указателькак правило, довольно быстро выйдет из области видимости, поскольку будет использоваться в присваивании или конструкторе.Кроме того, использование auto_ptr более четко указывает намеченное использование указателя, что всегда является плюсом, когда люди, незнакомые с вашим кодом, должны его понять.

2 голосов
/ 08 апреля 2011

Пример безопасен: если конструктор shared_ptr выдает исключение, он delete является аргументом своего указателя перед выбросом (черновик стандарта, 20.9.11.2.1).

Должно ли create возвращать shared_ptr, зависит от того, что его клиенты могут разумно хотеть сделать с его результатом. Если все, что они когда-либо делают, это обернуть его в shared_ptr, то верните это для дополнительной безопасности. (Да, shared_ptr может вводить некоторую связь.)

...