2

我对智能指针很陌生,并试图重构一些现有代码以使用 auto_ptr。我的问题是关于双指针和它们的 auto_ptr 等价物,如果这有意义的话。

我有一个接受双指针作为参数的函数,并且该函数为其分配资源:

void foo ( Image** img ) { ... *img = new Image(); ...}

然后像这样使用这个函数:

Image* img = NULL;
foo ( &img );
...
delete img;


我想使用 auto_ptr 来避免显式调用 delete 。以下是正确的吗?

void foo ( auto_ptr<Image>* img ) { ... *img = auto_ptr<Image>(new Image()); ...}

进而

auto_ptr<Image> img = NULL;
foo ( &img );

谢谢。

4

3 回答 3

7

std::auto_ptr<>具有奇怪的复制语义(实际上是移动语义,而不是复制语义),并且通常不是您想要智能指针时想要的。例如,它不能放入 STL 容器中。
如果您的标准库带有 TR1 支持,请std::tr1::shared_ptr<>改用。(如果没有,请使用boost's boost::shared_ptr<>,这是std::tr1::shared_ptr<>从中获取的。)

如果你想坚持std::auto_ptr<>你的代码,你可以将它传递给每个非const引用的函数:

void foo ( std::auto_ptr<Image>& img ) { ... img.reset(new Image();) ...}

std::auto_ptr<Image> img;
foo ( img );
...
// no need to delete

或者你可以只返回指针:

std::auto_ptr<Image> foo () {return std::auto_ptr<Image> img(new Image();)}
于 2010-04-29T08:02:03.383 回答
0

这取决于您的 STL 的 auto_ptr 实现是否覆盖“&”运算符以返回指针到指针(大多数智能指针类倾向于,但并非所有 auto_ptr 实现都这样做)。

如果你真的想重写你的代码来传递 auto_ptr 对象,那么你应该做更多这样的事情,这样会更安全:

void foo ( std::auto_ptr<Image> &img ) { ... img.reset(new Image()); ...}

std::auto_ptr<Image> img;
foo ( img );
于 2010-04-29T08:11:35.980 回答
0

由于您正在重构,我会更进一步,将参数转换为返回值:

// void foo( Image ** img )
std::auto_ptr<Image> foo() {
   std::auto_ptr<Image> tmp( new Image() );
   // ...
   return tmp;
}

即使我更喜欢从接口中删除要求(以便调用者可以决定更改代码以随意使用任何其他类型的智能指针):

Image* foo() {
   std::auto_ptr<Image> tmp( new Image() );
   // ...
   return tmp.release();
}
int main() {
   std::auto_ptr<Image> ptr( foo() );
}
于 2010-04-29T08:32:41.593 回答