c++ - 为什么 std::auto_ptr operator = 垃圾对象?

标签 c++ memory std

std::auto_ptr 和赋值似乎有问题,因此引用的对象似乎由于某种原因被丢弃了。

std::auto_ptr<AClass> someVar = new AClass();  // should work, but mangles content
std::auto_ptr<AClass> someVar( new AClass() ); // works fine.
std::auto_ptr<AClass> someVar = std::auto_ptr<AClass>(new AClass()); // works fine.

std::auto_ptr<AClass> someVar;
someVar.reset( new AClass() ); // works fine.

我已经对其进行了跟踪,看起来(通过观察调试器中的值)问题出现在从为包装 rhs 指针而创建的临时 std::auto_ptr_byref() 传输指针时。即进入auto_ptr(auto_ptr_ref<_Ty> _Right)函数时_Right中包含的值是正确的,但离开时_Myptr中的值是垃圾。

template<class _Ty>
    struct auto_ptr_ref
        {   // proxy reference for auto_ptr copying
    auto_ptr_ref(void *_Right)
        : _Ref(_Right)
        {   // construct from generic pointer to auto_ptr ptr
        }

    void *_Ref; // generic pointer to auto_ptr ptr
    };

template<class _Ty>
class auto_ptr
    {   // wrap an object pointer to ensure destruction
public:
typedef _Ty element_type;

explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
    : _Myptr(_Ptr)
    {   // construct from object pointer
    }

auto_ptr(auto_ptr<_Ty>& _Right) _THROW0()
    : _Myptr(_Right.release())
    {   // construct by assuming pointer from _Right auto_ptr
    }

auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
    {   // construct by assuming pointer from _Right auto_ptr_ref
    _Ty **_Pptr = (_Ty **)_Right._Ref;
    _Ty *_Ptr = *_Pptr;
    *_Pptr = 0; // release old
    _Myptr = _Ptr;  // reset this
    }
auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
{   // assign compatible _Right._Ref (assume pointer)
_Ty **_Pptr = (_Ty **)_Right._Ref;
_Ty *_Ptr = *_Pptr;
*_Pptr = 0; // release old
reset(_Ptr);    // set new
return (*this);
}

一开始我以为它搞乱了继承并切断了接口(interface),但即使该类只有一个父类,也会发生这种情况。

如果我们记得,我们可以避免使用 = new,通过使用括号或更改为在 rhs 上有一个显式的 std::auto_ptr temp,这当然容易出错。

只是这个版本的库被破坏了,还是我没有得到一些底层的东西?

我们还注意到将 std::auto_ptr 分配给 boot::shared_ptr 时存在类似的问题,尽管我们现在完全删除了它,我不记得是哪个语法导致了这个问题。

最佳答案

第一行:

std::auto_ptr<AClass> someVar = new AClass();  // should work, but mangles content

应该会导致编译器错误。因为原始 AClass 没有隐式转换指向 auto_ptr 的指针(带有原始指针的 auto_ptr 的构造函数标记为 explicit ),不允许使用“复制初始化程序”形式进行初始化。

VC9 给出如下错误:

C:\temp\test.cpp(23) : error C2440: 'initializing' : cannot convert from 'AClass *' to 'std::auto_ptr<_Ty>'

我试过的其他编译器(GCC 3.4.5、Comeau C/C++ 4.3.10.1、Digital Mars)给出了类似的错误。

编辑:

看起来这实际上是 VS2005 的 auto_ptr<> 实现中的一个错误。 (不确定它是在 SP1 中引入的还是从一开始就在 VS2005 中引入的)在 VS2008 中得到修复。这是该问题的 MS Connect 错误记录:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842&wa=wsignin1.0

关于c++ - 为什么 std::auto_ptr operator = 垃圾对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/427266/

相关文章:

c++ - 如何隐藏类的私有(private)成员?

c++ - 在统一内存 CUDA C/C++ 中分配一个二维 vector

c++ - 在 CUDA 上生成决策树

c++ - Visual C++ 2010 拒绝在调试时显示 std::string 值。显示 <Bad Ptr>

c++ - 支持多线程添加、删除和迭代器的线程安全 C++ std::set

c++ - 错误 : 'shuffle' is not a member of 'std'

c++ - 在 OpenGL 中渲染纹理 1 到 1

c++ - 如何使用Win32线程池API?

c++ - 传入引用与指针

Java:新生代使用 100%,Eden 空间使用 100%,From 空间使用 100%