在VC ++ 8中替换auto_ptr

时间:2008-11-06 21:26:28

标签: c++ smart-pointers

std::auto_ptr在VC ++ 8中被破坏(这是我们在工作中使用的)。我对它的主要抱怨是它允许auto_ptr<T> x = new T();,这当然会导致可怕的崩溃,而错误的做法很简单。

从这里的answer到另一个问题:stackoverflow:

  

请注意,Visual Studio 2005中std :: auto_ptr的实现严重受损。   http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98871   http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842

我想用

  • boost::scoped_ptr,指示不应传递所有权的指针。
  • boost::shared_ptr,用于容器中的指针以及需要它们的其他位置。
  • std::auto_ptr,指出应该/可以通过所有权的指针。

但是因为std::auto_ptr因为我而被打破,我想知道最好的方法是什么:

  • std::auto_ptr替换为网络中的内容。就像Rani Sharoni的this一样(尚未尝试过)。
  • 请改用boost::shared_ptr。当然会工作,虽然会有一些我不关心的小开销。但我想用auto_ptr来表示指针的意图。 (有关此方法的投票,请参阅this答案。)
  • 我永远不需要在实践中通过所有权,所以我不应该为此担心。

更新: 这是我做的: 我复制了Rani Sharoni提到的auto_ptr实现。 From here

做了一些小的测试:

class T
{
public:
    T() {
        OutputDebugStringA("T\n");
    };
    ~T() {
        OutputDebugStringA("~T\n");
    };
};

{
    fix::auto_ptr<T> x(new T); // This just works.
}
{
    fix::auto_ptr<T> x = (new T); // Doesn't compile. Great!
}
{
    fix::auto_ptr<T> x = fix::auto_ptr<T>(new T); // Transfer of ownership works also.
}

当然,这些测试并非详尽无遗,您不应该相信它们。实现异常安全模板类是毛茸茸的业务。至少这比内置的更好。

注意:关于版权,我不知道是否允许我使用此实现。我已经通过电子邮件发送了Rani,我正在等待回复。当我知道更多时,我会更新这篇文章。 允许每个人按照自己的意愿使用Rani Sharoni的auto_ptr实现。

感谢您的回复。

7 个答案:

答案 0 :(得分:7)

移动以提升智能指针。

与此同时,您可能希望从旧的/另一个STL中提取有效的auto_ptr实现,因此您可以使用工作代码。

我认为auto_ptr语义从根本上被打破 - 它节省了输入,但实际上界面并不简单:你仍然必须跟踪哪个实例是当前所有者并确保所有者离开最后。

unique-ptr“修复”,通过释放不仅放弃所有权,而且还将RHS设置为null。它是auto-ptr的最接近的替代品,但由于它的语义不同,它不是替代品。

有一篇介绍boost smart pointers的文章,嗯,我。

答案 1 :(得分:3)

您是否考虑过使用STLPort

答案 2 :(得分:2)

使用unique_ptr。我认为这些是一个更好的auto_ptr。

http://www.boost.org/doc/libs/1_35_0/doc/html/interprocess/interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.unique_ptr

事实上,我认为auto_ptr可能会被弃用以支持它:

http://objectmix.com/c/113487-std-auto_ptr-deprecated.html

答案 3 :(得分:1)

为什么你认为std :: auto_ptr&lt;&gt;坏了。

我会觉得那些与标准委员会报道的一样糟糕!

你的意思是你需要:

std::auto_ptr<T>   x(new T);  // Use the explicit constructor.

答案 4 :(得分:0)

使用boost :: shared_ptr / boost :: scoped_ptr。它将成为即将推出的C ++标准中的首选智能指针(已在TR1中)。

编辑: 请在此处找到相关的讨论:Idiomatic use of std::auto_ptr or only use shared_ptr?

答案 5 :(得分:0)

据我所知,不是吗:

auto_ptr<T> x = auto_ptr<T>(new T()); ??

答案 6 :(得分:0)

不是答案,但是对于与这些错误相关的任何人的普遍利益。有one more related bug与VC8的auto_ptr,这与隐式向上广播有关。它可能是最恶劣的一堆,因为其他错误只是让你根据标准编译其他非法的代码而不会失败,但至少兼容的代码工作正常。有了这个错误,实际符合的代码无法正常工作。

问题是这个。 Standard以这样的方式指定auto_ptr构造函数和转换运算符,它们支持auto_ptr的隐式向上转换,就像使用普通指针一样。但是,VC8的实现在那里执行reinterpret_cast而不是static_cast。当然,这不仅仅是英国。通过标准的字母,但它也打破了多个基类和/或虚拟继承。以下是由此打破的法律代码示例:

struct Base1 { int x; };
struct Base2 { int y; };
struct Derived : Base1, Base2 {};

std::auto_ptr<Derived> createDerived()
{
  return std::auto_ptr<Derived>(new Derived);
}

std::auto_ptr<Base2> base2(createDerived());

在我过去的一个工作中,当我们在生产中遇到这个问题时,我们最终只是自己修补了标题(这是一个简单的2行修复)。