Scheint ein Problem mit std::auto_ptr und Zuweisung zu haben, sodass das referenzierte Objekt aus irgendeinem Grund beschädigt zu werden scheint.
std::auto_ptr someVar = new AClass(); // sollte funktionieren, aber verändert den Inhalt
std::auto_ptr someVar( new AClass() ); // funktioniert einwandfrei.
std::auto_ptr someVar = std::auto_ptr(new AClass()); // funktioniert einwandfrei.
std::auto_ptr someVar;
someVar.reset( new AClass() ); // funktioniert einwandfrei.
Ich habe es verfolgt und es scheint (durch Beobachten der Werte im Debugger), dass das Problem beim Transfer des Zeigers von der temporären std::auto_ptr_byref() auftritt, die erstellt wird, um den rhs-Zeiger zu umschließen. Der Wert von _Right beim Betreten der Funktion auto_ptr(auto_ptr_ref<_Ty> _Right) ist korrekt, aber der Wert von _Myptr beim Verlassen ist Müll.
template
struct auto_ptr_ref
{ // Proxy-Referenz für auto_ptr-Kopieren
auto_ptr_ref(void *_Right)
: _Ref(_Right)
{ // Konstruktor aus generischem Zeiger auf auto_ptr-Zeiger
}
void *_Ref; // Generischer Zeiger auf auto_ptr-Zeiger
};
template
class auto_ptr
{ // Ein Objektzeiger einhüllen, um die Zerstörung sicherzustellen
public:
typedef _Ty element_type;
explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
: _Myptr(_Ptr)
{ // Konstruktor aus Objektzeiger
}
auto_ptr(auto_ptr<_Ty>& _Right) _THROW0()
: _Myptr(_Right.release())
{ // Konstruktor, indem der Zeiger von _Right auto_ptr angenommen wird
}
auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // Konstruktor, indem der Zeiger von _Right auto_ptr_ref angenommen wird
_Ty **_Pptr = (_Ty **)_Right._Ref;
_Ty *_Ptr = *_Pptr;
*_Pptr = 0; // Alten freigeben
_Myptr = _Ptr; // Diesen zurücksetzen
}
auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // Kompatibles _Right._Ref zuweisen (Zeiger annehmen)
_Ty **_Pptr = (_Ty **)_Right._Ref;
_Ty *_Ptr = *_Pptr;
*_Pptr = 0; // Alten freigeben
reset(_Ptr); // neues setzen
return (*this);
}
Zu Beginn dachte ich, es würde das Vererben durcheinanderbringen und Schnittstellen abschneiden, jedoch geschieht dies selbst, wenn die Klasse nur eine Elternklasse hat.
Wir können vermeiden, = new zu verwenden, wenn wir uns entweder an Klammern erinnern oder zu einem expliziten std::auto_ptr temp auf dem rhs wechseln, das ist natürlich fehleranfällig.
Handelt es sich nur um diese Version der Bibliothek, die defekt ist, oder um etwas grundlegendes, was ich nicht verstehe?
Wir haben auch ein ähnliches Problem mit der Zuweisung eines std::auto_ptr an ein boost::shared_ptr bemerkt, obwohl wir das jetzt komplett entfernt haben und ich mich nicht mehr daran erinnere, welche Syntax das Problem verursacht hat.