Smartpointer



  • Ich benutze Smartpointer und ReferenzZählung. Nach dem das nun schon eine ganze Weile sehr gut funktioniert tritt auf einmal ein Problem auf, wofür ich keine Erklärung habe.
    Mein Smartpointer sieht so aus:

    template <class T>  // T muss Klasse von Type BasisKlasse sein
    class RefP
    {
    private:
        T * pointer;
        void common();
    public:
        RefP();
        explicit RefP(T *ptr);
        RefP(RefP const& RP);
        ~RefP();
        RefP& operator=(RefP const&RP);
        T* operator->() const;
        T& operator*() const;
        operator bool();
        bool operator==(RefP const&);
        bool operator<(RefP const &) const;
    };
    //-----------------------------------------------------------------------------
    template <class T>
    RefP<T>::RefP():pointer(new T())
    { common();
    }
    //-----------------------------------------------------------------------------
    template <class T>
    RefP<T>::RefP(T* ptr) : pointer(ptr)
    {  common();
    }
    //-----------------------------------------------------------------------------
    template <class T>
    RefP<T>::RefP(RefP<T> const& RP) : pointer(RP.pointer)
    {  common();
    }
    //-----------------------------------------------------------------------------
    template <class T>
    void RefP<T>::common()
    {  if(pointer == 0) return;
       pointer->add_ref();
    }
    //-----------------------------------------------------------------------------
    template <class T>
    RefP<T>& RefP<T>::operator=(RefP<T> const&RP)
    {  if(pointer == RP.pointer) return *this;
       if(pointer) pointer->sub_ref();
       pointer = RP.pointer;
       common();
       return *this;
    }
    //-----------------------------------------------------------------------------
    template <class T>
    RefP<T>::~RefP()
    {  if(pointer) pointer->sub_ref();
    }
    

    Funktionier alles sehr gut.
    Folgender Code führt zum Problem:
    RefP<K> k = getK(); oder
    RefP<K> k(getK());
    getK() liefert ebenfalls einen entsprechenden Smartpointer.
    Nun kann es berechtigter Weise passieren, dass getK() eine Exeption wirft.
    Dabei passiert folgendes:
    k wird ohne initialisierung erzeugt, beim erzeugen des Parameters für den konstruktor wird eine exception geworfen, k wird zerstört, der Destruktor von k greift auf einen nicht definierten Zeiger zu, daraus folgt eine access violation innerhalb einer Exception und das bringt ein Terminate.
    Einwandfrei funktioniert deshalb:
    RefP<K> k;
    k = getK();

    Ich verstehe nur nicht, warum das solange funktioniert hat.(Auch das saubere abfangen der exception)
    Deshalb meine Fragen:
    Ist das eben so und ich muss mich irren, das kann nie funktioniert haben?
    Mache ich etwas falsch?
    Kann man im BCB6 eine Option einstellen, die ich vieleicht unwissender weise verstellt habe?

    Ich hoffe ich war verständlich



  • gh schrieb:

    Kann man im BCB6 eine Option einstellen, die ich vieleicht unwissender weise verstellt habe?

    Unwahrscheinlich, deshalb verschoben nach "C++".



  • seltsam. Der Destruktor von k dürfte nicht aufgerufen werden, da auch der Konstruktor nie aufgerufen wurde.



  • Hast du das auch mal mit einem anderen Compiler ausprobiert?



  • Ich finde das ja auch hoechst seltsam, aber ich habe sehr lange debuggt bis ich auf den Dreh gekommen bin, daß der Mistkerl dem Destruktor aufruft, obwohl der Konstruktor noch nicht aufgerufen wurde.
    Ich kenne gar keinen anderen Compiler.


Anmelden zum Antworten