4

我看到了下面的代码,

#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<_Ty>::auto_ptr(std::auto_ptr<_Ty> &) throw()' : cannot convert parameter 1 from 'Fred *' to ' std::auto_ptr<_Ty> &'

代码复制自 C++ FAQ 12.15。

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

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

这段代码可以通过VC8.0编译。但我不确定这是否是一个正确的修复。

4

3 回答 3

6

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

此代码不会编译。

于 2011-01-01T22:21:16.430 回答
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->doSomething( ) 可能会导致段错误。使 auto_ptr 构造函数显式是一种防范措施;当其他人认为他们已经拥有该访问权限时,您不希望意外获得资源的独占所有权。

于 2011-01-02T00:09:18.523 回答
0

代码的固定版本 ( return std::auto_ptr<Fred>(new Fred())) 是正确且有效的 C++。但是,我不确定该create()函数会给您带来什么,因为创建 astd::auto_ptr<T>应该在任何 C++ 程序员的技能范围内。同样,除了需要查看 a 的真正含义之外typedef,我不清楚std::auto_ptr<Fred>要买什么。FredPtrFredPtr

于 2011-01-02T00:23:27.497 回答