I'm quite new to smart pointers and was trying to refactor some existing code to use auto_ptr. The question I have is about double pointers and their auto_ptr equivalent, if that makes sense.
I have a function that accepts 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 having to call delete explicitly. Is the following correct?
开发者_如何学Cvoid foo ( auto_ptr<Image>* img ) { ... *img = auto_ptr<Image>(new Image()); ...}
and then
auto_ptr<Image> img = NULL;
foo ( &img );
Thanks.
std::auto_ptr<>
has weird copy semantics (actually it's move semantics, rather than copy semantics) and is often not what you want when you want 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<>
instead. (If it doesn't, use boost's boost::shared_ptr<>
, which is what std::tr1::shared_ptr<>
was taken from.)
If you want to stick with std::auto_ptr<>
for your code, you can pass it into the function per non-const
reference:
void foo ( std::auto_ptr<Image>& img ) { ... img.reset(new Image();) ...}
std::auto_ptr<Image> img;
foo ( img );
...
// no need to delete
Or you could just return the pointer:
std::auto_ptr<Image> foo () {return std::auto_ptr<Image> img(new Image();)}
It depends on whether or not your STL's implementaton of auto_ptr overrides the '&' operator to return a pointer-to-pointer (most smart pointer classes tend to, but not all auto_ptr implementations do).
If you really want to re-write your code to pass auto_ptr objects around, then you should do something more like this instead, which would be safer:
void foo ( std::auto_ptr<Image> &img ) { ... img.reset(new Image()); ...}
std::auto_ptr<Image> img;
foo ( img );
Since you are refactoring, I would go one step further and convert the parameter into 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 removing the requirement from the interface (so that the caller can decide to change the code to use any other type of smart pointer at will):
Image* foo() {
std::auto_ptr<Image> tmp( new Image() );
// ...
return tmp.release();
}
int main() {
std::auto_ptr<Image> ptr( foo() );
}
精彩评论