auto_ptr能够防止这种情况发生吗?

4

我不太清楚auto_ptr是否能帮助我解决这个问题:

class A
{
  A(const B& member)
   : _member(B)
  {};

...
  const B& _member;
};


A generateA() {
   auto_ptr<B> smart(new B());
   A myA(*smart);
   return myA;
}

smart 离开其封闭作用域时,myA._member 引用仍然有效吗? 如果 auto_ptr 在这里不是答案,那么什么是答案?

编辑:我看到我让大家困惑的地方; 我必须在作用域之外返回 myA,这就是为什么我关心 smart 退出作用域后 _member 是否有效。

3个回答

6

这不会有所帮助,_member将变成悬挂句柄。这是因为auto_ptr保证在作用域结束时自动销毁:没有更多的,也不会更少。

有两个可能的答案。

  • 你可以使_member的类型为boost::shared_ptr<const B>
  • 或者,如果类B是小型可复制单态的,并且不需要保留对象身份,那么你可以将_member设置为值,并将参数的副本存储在其中。这是目前最简单的选择,但显然它非常有限。

回应您的编辑:确实是我所谈论的情况。通过按值返回myA,将创建一个副本,副本的_member引用了已经被销毁的局部变量。如描述的,shared_ptr和值语义都可以解决这个问题。


1
不需要将原始类型 shared_ptr 也共享。shared_ptr 有一个构造函数,它接受一个 std::auto_ptr 并从中获取所有权。 - Evan Teran
好的,没想到那个方法 :) 不过,出于清晰明了的考虑,我会将两个对象都转换为shared_ptr。 - Iraimbilanja
请将以下有关编程的内容从英语翻译成中文。仅返回翻译后的文本: - Iraimbilanja
请注意,在给出的示例中,不会有悬空句柄,因为智能指针和它被复制到的类具有相同的作用域。但这是一个糟糕的示例,如果没有字面意义,您可能已经捕捉到了问题的精神。 - Dan Olson
然而,如果你通过值返回myA,或将其传递给某个存储它的人,稍后再使用它,那么_copy_中的成员引用将会悬空。而_shared_ptr_就是保护你免受这种情况的影响。 - Iraimbilanja
显示剩余3条评论

2
auto_ptr类是普通指针的包装器。当堆栈被展开时(auto_ptr的析构函数被调用,从而释放您包含的对象),它们负责解除分配。
请注意,您的A对象也在堆栈上创建。当范围结束时,A和auto_ptr都将被解除分配。在此之后尝试访问A对象将导致编译时错误。
假设A对象在块外某处创建,则存在真正的问题。由于A对象存储对B对象的引用,在块作用域之外,此引用变得无效。
还要注意,使用C++0x,auto_ptr已被弃用。请改用unique_ptr。请查看即将推出的C++0x中的通用智能指针

0
{
   auto_ptr<B> smart(new B());
   A myA(*smart);
}

在此作用域的末尾,指针'smart'和对象'myA'都将被销毁。但这应该是您想要的代码片段。

一旦作用域结束,'myA'将首先被销毁(它是最后声明的)。
然后,在此之后,将销毁smart并且其析构函数将删除指针。

由于无法引用'smart'或'myA',因此我希望您希望在此时删除指针。

或者,您可以这样做:

{
    B  myB;
    A  myA(myB);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接