Ответ 1
Возврат std::unique_ptr
из метода factory является прекрасным и должен быть рекомендуемой практикой. Сообщение, которое оно передает (IMO): Теперь вы являетесь единственным владельцем этого объекта. Кроме того, для вашего удобства объект знает, как уничтожить себя.
Я думаю, что это намного лучше, чем возврат необработанного указателя (где клиент должен помнить, как и если удалять этот указатель).
Однако я не понимаю вашего комментария об освобождении указателя, чтобы продлить его срок службы. В общем, я редко вижу какую-либо причину вызова release
на smartpointer, так как я считаю, что указатели всегда должны управляться какой-то структурой RAII (примерно единственная ситуация, когда я называю release
), - это поместить указатель в другую управляя структурой данных, например a unique_ptr
с другим делетером, после того, как я сделал что-то, чтобы гарантировать дополнительную очистку).
Поэтому клиент может (и должен) просто хранить unique_ptr
где-то (например, другой unique_ptr
, который был перемещен, построенный из возвращенного), если им нужен объект (или shared_ptr
, если им нужно несколько копий указателя). Таким образом, код clientside должен выглядеть следующим образом:
std::unique_ptr<FooBar> myFoo = Foobar::factory(data);
//or:
std::shared_ptr<FooBar> myFoo = Foobar::factory(data);
Лично я также добавил бы typedef
для возвращаемого типа указателя (в данном случае std::unique_ptr<Foobar>
) и или используемого делетера (в данном случае std:: default_deleter) для вашего объекта factory. Это упростит, если позже вы решите изменить выделение своего указателя (и, следовательно, необходимо использовать другой метод для уничтожения указателя, который будет отображаться в качестве второго параметра шаблона std::unique_ptr
).
Поэтому я бы сделал что-то вроде этого:
class Foobar {
public:
typedef std::default_deleter<Foobar> deleter;
typedef std::unique_ptr<Foobar, deleter> unique_ptr;
static unique_ptr factory(DataObject data);
}
Foobar::unique_ptr myFoo = Foobar::factory(data);
//or:
std::shared_ptr<Foobar> myFoo = Foobar::factory(data);