views:

118

answers:

4

In my class the constructor is private and I added a static method "CreateMyClassPtr" that uses the constructor and returns a share_ptr of it.

Is it the correct implementation?

Do you think I even have to make sure that shared_ptr will be used? Should I maybe leave it to the user to decide?

A: 

If you going to expose your class to clients, then don't force them to use shared pointers. They know that they create an object and they are responsible for its deletion.

They then easily can write

myfavorite::api::shared_ptr<Class> object(Class::create());

or

std::auto_ptr<Class> object(Class::create());
Mykola Golubyev
+3  A: 

If you aren't holding onto any copies of it but you want the user to delete the pointed-to-object using delete then you can return a std::auto_ptr by value. It doesn't add any dependencies (auto_ptr is part of the standard) and it makes your interface clearly communicate the requirement that the object needs to be deleted.

If the user wants to, then they can release the pointer and do things manually or move it into their shared smart pointer framework.

Charles Bailey
+1 I forgot to mention in my answer the importance of the interface helping with the semantics: `auto_ptr` implies transfer of ownership.
David Rodríguez - dribeas
auto_ptr is evil, especially when you inadvertantly pass them around by value... boost::scoped_ptr is much better in this respect.
Alexandre C.
@Alexandre C.: For this usage `boost::scoped_ptr` is totally inappropriate. As it's not copyable it can't even be used as a return value. `std::auto_ptr` is not evil in the same way that a chainsaw is not evil. The are just tools; they have no intent. Just because juggling chainsaws is very dangerous doesn't mean that they don't have a useful application: cutting down trees. There are better standard ways of expressing transfer of ownership in C++0x (e.g. unique_ptr - although arguably the better interface is only possible thanks to rvalue references), but at least `std::auto_ptr` is here now.
Charles Bailey
+2  A: 

Is the element really shared? That is, after creation, do you keep a pointer into the object for your own purposes or are you doing this just to avoid user memory leaks?

If the memory is not actually shared I would not use a shared_ptr. Note that by using shared_ptr as your return type you are forcing the use of both dynamic allocation and a particular implementation of a smart pointer, but limiting the use of the stack for your type and other smart pointer types that might be more appropriate (you cannot extract membership from a shared pointer)

If you really want to make sure that the call will not leak (that is, if the user calls your function the returned memory will be handled 'somehow', you could use std::auto_ptr or boost::unique_ptr (the last one being unstandard even in C++0x). Both solutions allow calling code to extract the pointer from the smart pointer and use a different approach to memory management (even if it can be cumbersome in some cases).

struct type {
   std::auto_ptr<type> create(); 
};
std::auto_ptr<type> ap = type::create();
std::shared_ptr<type> sp( type::create().release() );
type::create(); // will not leak memory
type *rp = type::create().release(); // user specifically requested a raw pointer!
David Rodríguez - dribeas
+1  A: 

That will work, yes. However, are you sure you need it? There are circumstances where this is appropriate, but you are really limiting your options when you do so. There are other forms of smart pointers users might want to utilize, not to mention that you are eliminating stack-based allocation as an option when you hide your constructors that way.

Dennis Zickefoose