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

C++ 为什么std::auto_ptr operator=垃圾对象?,c++,memory,std,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

似乎在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.
std::auto_ptr someVar=new AClass();//应该有用,但会破坏内容
std::auto_ptr someVar(new AClass());//很好。
std::auto_ptr someVar=std::auto_ptr(new AClass());//很好。
std::auto_ptr someVar;
someVar.reset(新AClass());//很好。
我已经跟踪了它,并且(通过观察调试器中的值)显示问题发生在从临时std::auto_ptr_byref()传输指针的过程中,临时std::auto_ptr_byref()是为包装rhs指针而创建的。这是输入auto_ptr(auto_ptr_ref _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);
}
模板
结构自动\u ptr\u ref
{//用于自动\u ptr复制的代理引用
自动ptr ref(无效*\右侧)
:_Ref(_Right)
{//从泛型指针构造到自动\u ptr ptr
}
void*\u Ref;//指向auto\u ptr ptr的通用指针
};
模板
自动类
{//包装对象指针以确保销毁
公众:
typedef_Ty element_type;
显式自动\u ptr(\u Ty*\u ptr=0)\u THROW0()
:_Myptr(_Ptr)
{//从对象指针构造
}
auto_ptr(auto_ptr&_Right)_THROW0()
:_Myptr(_Right.release())
{//通过假定指针来自_rightauto_ptr来构造
}
auto_ptr(auto_ptr_ref _Right)_THROW0()
{//通过假定指针来自_rightauto_ptr_ref来构造
_Ty**Pptr=(Ty**)右;
_Ty*_Ptr=*_Pptr;
*_Pptr=0;//释放旧版本
_Myptr=\u Ptr;//重置此
}
auto_ptr&operator=(auto_ptr_ref _Right)_THROW0()
{//将兼容的_分配到右边。_Ref(假定指针)
_Ty**Pptr=(Ty**)右;
_Ty*_Ptr=*_Pptr;
*_Pptr=0;//释放旧版本
重置(_Ptr);//设置新
返回(*本条);
}
起初,我认为这会弄乱继承和切分接口,但即使该类只有一个父类,也会发生这种情况

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

是这个版本的库被破坏了,还是一些我根本不了解的东西


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

Edited:Michael说得很对,这是一个编译错误,所以您使用的是哪个编译器?您需要调用
reset
将新值放入auto_ptr中。

他说了第一句话:

std::auto_ptr<AClass> someVar = new AClass();  // should work, but mangles content
我尝试过的其他编译器(GCC 3.4.5、Comeau C/C++4.3.10.1、Digital Mars)也给出了类似的错误

编辑:

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


VC++中VC6和VC9之间的已知错误:

您使用的编译器和版本是什么?有关第一行和第二行之间的差异的讨论,请参阅。这很有趣,但没有直接帮助解决问题我不知道您的情况,但如果可能,我建议重构以使用boost/TR1智能指针d、
auto_ptr
很难使用和推理,例如不能存储在STL容器中。第一行与运算符=();这是一个初始化,不是赋值。有一个接受auto_ptr的ctor和一个接受raw指针的ctor。raw指针ctor是显式的,因此没有从raw指针到auto_ptr的转换。@wilhelmtell-你是对的。我在你指出错误的同时修复了它。而一次优化将e调用ctor并初始化,它不会这样做。在MSVC 2005中,库中引入了auto_ptr_ref,而将其构造为一个临时rhs。在以前的版本中,我无法执行第1行,是的,我曾经遇到过该错误。如MSVC8库中提供的文件副本所示,您正确地认为原始ptr是显式的但是,auto_ptr_ref不是显式的,auto_ptr_ref的构造函数也不是显式的(库中的更改造成了最大的痛苦!您的链接有点损坏。(我没有足够的代表来修复它。)
C:\temp\test.cpp(23) : error C2440: 'initializing' : cannot convert from 'AClass *' to 'std::auto_ptr<_Ty>'