C ++ - 这里是否存在从Fred *到auto_ptr <fred>的隐式转换?</fred>

时间:2011-01-01 22:16:43

标签: c++ smart-pointers auto-ptr

我看到了以下代码,

#include <new>
#include <memory>
using namespace std;

class Fred;  // Forward declaration
typedef  auto_ptr<Fred>  FredPtr;

class Fred {
public:
  static FredPtr create(int i)
  { 
    return new Fred(i); // Is there an implicit casting here? If not, how can we return
                        // a Fred* with return value as FredPtr?
  }
private:
  Fred(int i=10)      : i_(i)    { }
  Fred(const Fred& x) : i_(x.i_) { }
  int i_;
};

请参阅功能创建中列出的问题。

谢谢

//基于评论更新

是的,代码无法通过VC8.0 错误C2664:'std :: auto_ptr&lt; _Ty&gt; :: auto_ptr(std :: auto_ptr&lt; _Ty&gt;&amp;)throw()':无法将参数1从'Fred *'转换为'std :: auto_ptr&lt; _Ty&gt; &安培;'

代码是从C ++ FAQ 12.15中复制的。

但是,在进行以下更改后,

replace 
  return new Fred(i);
with
  return auto_ptr<Fred>(new Fred(i));

此代码可以通过VC8.0编译器。但我不确定这是否是正确的解决办法。

3 个答案:

答案 0 :(得分:6)

std::auto_ptr有一个构造函数,它将一个原始指针作为参数,但该构造函数是explicit,不能用作转换构造函数。

此代码无法编译。

答案 1 :(得分:3)

不,不存在这种隐式转换。事实证明,这实际上是一件好事。例如,请考虑以下代码:

void MyFunction(const std::auto_ptr<Fred>& myFred) {
   /* ... do something to Fred. */
}

int main() {
    Fred* f = new Fred;
    MyFunction(f); // Not legal, but assume it is.
    f->doSomething();
}

这里,如果您可以将原始指针传递给Fred进入MyFunction,那么当该函数返回并且临时auto_ptr对象被清理时,您在main()中分配的内存将被回收,并且对f-的调用&gt; doSomething()可能会导致段错误。使auto_ptr构造函数显式是一种保护措施;当其他人认为他们已经拥有该访问权限时,您不希望意外获得资源的独占所有权。

答案 2 :(得分:0)

代码的固定版本(return std::auto_ptr<Fred>(new Fred()))是正确且有效的C ++。但是,我不确定create()函数对你的影响是什么,创建std::auto_ptr<T>应该在任何C ++程序员的技能集中。同样,除了需要查找typedef真正的内容之外,我不清楚std::auto_ptr<Fred> FredPtr FredPtr向{{1}}购买的内容。