3

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);
}

最初は、継承を台無しにしてインターフェイスを切り離していると思っていましたが、これは、クラスに親クラスが 1 つしかない場合でも発生します。

ブラケットを使用するか、rhs で明示的な std::auto_ptr temp を持つように変更することで、覚えていれば = new を回避できますが、これはもちろんエラーが発生しやすくなります。

このバージョンのライブラリが壊れているだけですか、それとも根本的な問題が発生していないだけですか?

また、std::auto_ptr を boot::shared_ptr に割り当てることで同様の問題が発生しましたが、現在は完全に削除されており、どの構文が問題を引き起こしたかは思い出せません。

4

3 に答える 3

10

最初の行:

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

コンパイラ エラーが発生するはずです。AClass生ポインタから an への暗黙的な変換がないため(生ポインタを取るauto_ptran のコンストラクタは とマークされています)、「コピー初期化子」形式を使用した初期化は許可されていません。 auto_ptrexplicit

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) でも同様のエラーが発生します。

編集:

これは実際には、VS2008 で修正された VS2005 の実装のバグauto_ptr<>(SP1 で導入されたのか、最初から VS2005 にあったのかは不明) のようです。この問題に関する MS Connect のバグ レコードは次のとおりです。

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

于 2009-01-09T07:01:56.670 に答える
4

VC6 と VC9 の間の VC++ の既知のバグ: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842

于 2009-01-09T09:05:17.437 に答える
0

編集: マイケルの言うとおりです。これはコンパイル エラーです。どのコンパイラを使用していますか? resetauto_ptr に新しい値を入れるために呼び出す必要があります。

于 2009-01-09T06:57:55.430 に答える