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;
}

离开其封闭范围时,myA._member引用是否有效?smart如果 auto_ptr 不是这里的答案,那是什么?

编辑:我看到我让每个人都感到困惑的地方;我必须将 myA 返回范围之外,这就是为什么我关心 _member 在 smart 退出范围后是否有效。

4

3 回答 3

6

它不会帮助你。_member 将成为一个悬垂的句柄。这是因为auto_ptr保证在范围结束时销毁:不多也不少

有2个可能的答案。

  • 您可以制作 _member 的类型boost::shared_ptr<const B>
  • 或者,如果类 B 是smallcopyablemonomorphic ,并且不需要保留对象标识,则可以将 _member 设为值,并将参数的副本存储在那里。这是迄今为止最简单的选择,但显然它非常有限。

回应您的编辑:这确实是我所说的情况。通过按值返回 myA ,创建了一个副本,并且该副本的 _member 引用了已经破坏的本地。如前所述,shared_ptr值语义和值语义都解决了这个问题。

于 2009-03-09T17:45:55.890 回答
2

该类auto_ptr是普通指针的包装器。当堆栈展开时,它们会负责解除分配(auto_ptr调用的析构函数又会释放您包含的对象)。

请注意,您的A对象也是在堆栈上创建的。当作用域结束时,A 和 auto_ptr 都将被释放。超过这一点,试图访问该A对象会给你一个编译时错误。

假设A对象是在块之外的某个地方创建的,那么你就有一个真正的问题。由于对象在块范围之外A存储了对该对象的引用,因此该引用变得无效。B

另请注意,对于 C++0x,auto_ptr已弃用。改用 a unique_ptr。请查看C++0x 中出现的通用智能指针。

于 2009-03-09T17:47:31.800 回答
0
{
   auto_ptr<B> smart(new B());
   A myA(*smart);
}

保存在“smart”中的指针和对象“myA”都将在此范围的末尾被销毁。但这应该是你想要的这段代码。

一旦范围结束,“myA”将首先被销毁(最后声明)。
然后这个 smart 将被销毁,其析构函数将删除指针。

由于无法引用“smart”或“myA”,我希望您此时希望删除该指针。

或者,您可以这样做:

{
    B  myB;
    A  myA(myB);
}
于 2009-03-09T18:40:38.473 回答