Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What type of smart pointer should a factory method return?

9 views
Skip to first unread message

francis_r

unread,
Sep 12, 2008, 5:02:07 PM9/12/08
to
In my application I have a factory method that creates an object on
the heap, and another object that ends up owning it. Right now my
factory returns a shared_ptr, and the owner stores it as a shared_ptr
as well. This solution has actually been working very well.

However, my pointers are not really shared among different objects, so
a shared_ptr is not needed. I have been trying come up with a better
solution. For the owner I can use boost::scoped_ptr. However for the
factory it is not obvious to me what type of pointer it should return.
Options would be to return a raw pointer or an auto_ptr. The auto_ptr
seems the correct choice, but I remember reading that it will become
deprecated in the future. And a raw pointer could cause a memory leak
if an exception would get thrown in between creating and assigning to
owner.

So what would be the correct solution then?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Niels Dekker - no return address

unread,
Sep 12, 2008, 10:16:38 PM9/12/08
to
francis_r wrote:
> In my application I have a factory method that creates an object on
> the heap, and another object that ends up owning it. Right now my
> factory returns a shared_ptr, and the owner stores it as a shared_ptr
> as well. This solution has actually been working very well.
>
> However, my pointers are not really shared among different objects, so
> a shared_ptr is not needed. I have been trying come up with a better
> solution. For the owner I can use boost::scoped_ptr. However for the
> factory it is not obvious to me what type of pointer it should return.
> Options would be to return a raw pointer or an auto_ptr.

The following (draft) article may be helpful to you:
THE RESOURCE RETURN PROBLEM - Scott Meyers, 2004
http://www.aristeia.com/Papers/resourceReturnProblem.txt

HTH,
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center

Jonathan Jones

unread,
Sep 12, 2008, 10:14:25 PM9/12/08
to
In article
<d35f5c5e-f051-4b1c...@k30g2000hse.googlegroups.com>,
francis_r <francis....@gmail.com> wrote:

> In my application I have a factory method that creates an object on
> the heap, and another object that ends up owning it. Right now my
> factory returns a shared_ptr, and the owner stores it as a shared_ptr
> as well. This solution has actually been working very well.
>
> However, my pointers are not really shared among different objects, so
> a shared_ptr is not needed. I have been trying come up with a better
> solution. For the owner I can use boost::scoped_ptr. However for the
> factory it is not obvious to me what type of pointer it should return.
> Options would be to return a raw pointer or an auto_ptr. The auto_ptr
> seems the correct choice, but I remember reading that it will become
> deprecated in the future. And a raw pointer could cause a memory leak
> if an exception would get thrown in between creating and assigning to
> owner.
>
> So what would be the correct solution then?

I was unaware of std::auto_ptr being deprecated. It seems to me that
std::auto_ptr is the correct choice, since it nicely describes the
ownership transfer happening between the factory and the caller.

Joshua...@gmail.com

unread,
Sep 12, 2008, 10:14:15 PM9/12/08
to
On Sep 12, 2:02 pm, francis_r <francis.ramme...@gmail.com> wrote:
[snip]

> And a raw pointer could cause a memory leak
> if an exception would get thrown in between creating and assigning to
> owner.

I don't understand what you mean here. The factory function could look
like
#include <memory>
class A { public: virtual ~A() = 0; };
A::~A() {}
class B : public A { /*implementation details*/ };
A* factory()
{ std::auto_ptr<A> result(new B);
//code
return result.release();
}

User code could look like
#include <memory>
class A { public: virtual ~A() = 0; };
A* factory();
void foo()
{ std::auto_ptr<A> x(factory());
//stuff
//implicitly freeing on error paths
//success paths assign it a more permanent owner
}

I don't see the leak possibility that you referenced.

At least in this particular case, there is no possible exception that
may be thrown between the start release() in factory() and the end of
the auto_ptr constructor in foo(), thus there is no possible leak.

If you do use a structure which can throw when you give it a pointer,
then yes, your problem does exist. Don't write such code. For example,
the here is user could badly written
#include <vector>
class A { public: virtual ~A() = 0; };
A* factory();
void foo()
{ std::vector<A*> vec;
vec.push_back(factory());
delete vec[0];
}
The previous example could leak. You could write it correctly as
#include <vector>
class A { public: virtual ~A() = 0; };
A* factory();
void foo()
{ std::vector<A*> vec;
vec.push_back(0);
vec.back() = factory();
delete vec[0];
}
Or you could write it correctly as
#include <vector>
#include <memory>
class A { public: virtual ~A() = 0; };
A* factory();
void foo()
{ std::vector<A*> vec;
std::auto_ptr<A> tmp(factory());
vec.push_back(tmp.get());
tmp.release();
delete vec[0];
}
etc.

Now, if you're wary of auto_ptr, then use whatever basic auto_ptr
replacement you want.

Note that I'm not commenting on the correct course of action. I'm just
saying that you can use the raw pointer approach sanely. operator new
and operator delete work on raw pointers, and we've managed to deal
with them, though we tend to encapsulate new, delete, and the raw
pointers when possible.

Mathias Gaunard

unread,
Sep 12, 2008, 10:28:49 PM9/12/08
to
On 12 sep, 23:02, francis_r <francis.ramme...@gmail.com> wrote:
> The auto_ptr
> seems the correct choice, but I remember reading that it will become
> deprecated in the future.
> [...]

> So what would be the correct solution then?

The correct solution would be the one that replaces auto_ptr,
unique_ptr.
It is C++0x only, though.

Seungbeom Kim

unread,
Sep 12, 2008, 10:28:50 PM9/12/08
to
francis_r wrote:
> In my application I have a factory method that creates an object on
> the heap, and another object that ends up owning it. Right now my
> factory returns a shared_ptr, and the owner stores it as a shared_ptr
> as well. This solution has actually been working very well.
>
> However, my pointers are not really shared among different objects, so
> a shared_ptr is not needed. I have been trying come up with a better
> solution. For the owner I can use boost::scoped_ptr. However for the
> factory it is not obvious to me what type of pointer it should return.
> Options would be to return a raw pointer or an auto_ptr. The auto_ptr
> seems the correct choice, but I remember reading that it will become
> deprecated in the future. And a raw pointer could cause a memory leak
> if an exception would get thrown in between creating and assigning to
> owner.
>
> So what would be the correct solution then?

Until the next standard is released, auto_ptr looks like the correct
choice. It will be deprecated only in the next standard, which will
provide us with a better solution called unique_ptr.

--
Seungbeom Kim

0 new messages