Pointer to auto_ptr instead of classic double pointer
I'm new to smart pointers and was trying to refactor some existing code to use auto_ptr. I have a question about double pointers and their auto_ptr equivalent, if that makes sense.
I have a function that takes a double pointer as its parameter and the function allocates resources for it:
void foo ( Image** img ) { ... *img = new Image(); ...}
This function is then used like this:
Image* img = NULL;
foo ( &img );
...
delete img;
I want to use auto_ptr to avoid calling delete directly. Is it correct?
void foo ( auto_ptr<Image>* img ) { ... *img = auto_ptr<Image>(new Image()); ...}
and then
auto_ptr<Image> img = NULL;
foo ( &img );
Thanks.
a source to share
std::auto_ptr<>
has strange copy semantics (it actually moves semantics, not copy semantics) and is often not what you want when you need a smart pointer. For example, it cannot be put into STL containers.
If your standard library comes with TR1 support, use std::tr1::shared_ptr<>
. (If not, use the boost you came boost::shared_ptr<>
from std::tr1::shared_ptr<>
.)
If you want to stick std::auto_ptr<>
around for your code, you can pass it to a function for reference without const
:
void foo ( std::auto_ptr<Image>& img ) { ... img.reset(new Image();) ...}
std::auto_ptr<Image> img;
foo ( img );
...
// no need to delete
Or you can just return a pointer:
std::auto_ptr<Image> foo () {return std::auto_ptr<Image> img(new Image();)}
a source to share
It depends on whether your STL auto_ptr overrides the '&' operator parameter to return a pointer to a pointer (most smart pointer classes tend, but not all auto_ptr implementations).
If you really want to rewrite your code to pass auto_ptr objects, you should do something more like this, which is safer:
void foo ( std::auto_ptr<Image> &img ) { ... img.reset(new Image()); ...}
std::auto_ptr<Image> img;
foo ( img );
a source to share
Since you are refactoring, I would go one step further and convert the parameter to a return value:
// void foo( Image ** img )
std::auto_ptr<Image> foo() {
std::auto_ptr<Image> tmp( new Image() );
// ...
return tmp;
}
Even if I prefer to remove the requirement from the interface (so the caller can decide to change the code to use any other type of smart pointer as they see fit):
Image* foo() {
std::auto_ptr<Image> tmp( new Image() );
// ...
return tmp.release();
}
int main() {
std::auto_ptr<Image> ptr( foo() );
}
a source to share