Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Smart pointer

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
02.11.2002, 19:55 Uhr
MarcDuerner



Hi ,
ich habe folgenden smart pointer geschrieben, aber ich weiss nicht wieso beim
initialisieren des smart pointers zwei referenzen erzeugt werden und eine
gleich wieder gelöscht wird:


Code:
Object constructed.
new reference...
Increased number of references to:1
new reference...
Increased number of references to:2 <- die ist zuviel !
smart pointer destructs...  <- wird aber gleich wieder gelöscht.
Decreased number of references to:1
smart pointer destructs...
Decreased number of references to:0
Object destroyed.



Marc


Code:

C++:
#include <iostream.h>
#include <stdlib.h>



template <class T> class GC_Ptr
{
private:
    T* pointer;

public:
    GC_Ptr(T* pointer_)
        {
            pointer = pointer_;cout << "new reference..." << endl;
            pointer->newObject();
        }

    GC_Ptr( GC_Ptr<T>& t )
        {
            cout << "assigned other GC_Ptr..." << endl;
            pointer = t;
            pointer->newObject();
        }

    ~GC_Ptr()
        {cout << "smart pointer destructs..." << endl; pointer->deleteObject();}

    operator T*(void)
        {return pointer;}

    T* operator ->(void)
        {return pointer;}

    T& operator*(void)
        {return *pointer;}

    GC_Ptr& operator = (GC_Ptr<T> & gc_ptr)
        {return operator=((T*) gc_ptr);}

    GC_Ptr& operator = (T* pointer_)
        {
            pointer->deleteObject();
            pointer = pointer_;
            pointer->newObject();
            return *this;
        }

};




class GCObject
{
public:
    GCObject();
    ~GCObject();
    void newObject();
    void deleteObject();

private:
    int ReferenceCounter;

};

GCObject::GCObject()
{
ReferenceCounter=0;
cout << "Object constructed." << endl;
}


GCObject::~GCObject()
{
cout << "Object destroyed." << endl;
}


void GCObject::newObject()
{
ReferenceCounter++;
cout << "Increased number of references to:" <<  ReferenceCounter <<endl;

}

void GCObject::deleteObject()
{
ReferenceCounter--;
cout << "Decreased number of references to:" << ReferenceCounter << endl;
if(ReferenceCounter<1){delete this;}
}





class MyObject : public GCObject
{

public:
    void MyFunction();
    int i;
};

void MyObject::MyFunction()
{
cout << "MyFunction was called." << endl;
}




int main(int argc, char *argv[])
{

GC_Ptr<MyObject> p1 = new MyObject();
return EXIT_SUCCESS;
}



Edit by virtual: Codetags eingefügt

Dieser Post wurde am 02.11.2002 um 22:02 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
02.11.2002, 22:39 Uhr
virtual
Sexiest Bit alive
(Operator)


Generell ist das kein guter Smartpointer, weil er erfordert, dass die Klasse, die als Template Argument übergeben wird, newObject und deleteObject bereitsstellt. Eine gute Implementierung würde die Smartpointer eigenschaft komplett kapseln.

Auch stellst Du etwas merkwürdige Constructoren zur Verfügung:

C++:
GC_Ptr( GC_Ptr<T>& t ) ...

Ich möchte fast wetten, wenn Du hier ein

C++:
GC_Ptr(const GC_Ptr<T>& t ) ...

verwenden würdest, wärst Du auch das temp. Object los, was dich stört.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
02.11.2002, 23:22 Uhr
MarcDuerner



Danke!
Das scheint zu funktionieren:

C++:
    GC_Ptr( const GC_Ptr<T>& t )
        {
            cout << "assigned other GC_Ptr..." << endl;
            pointer = const_cast<GC_Ptr<T>&>(t);
            pointer->newObject();
        }



Was war denn genau der Grund weshalb vorher ein temp object zustande kam?
Was macht denn das const?

Auch hast du angemerkt das es kein guter smart pointer ist, weil ich objecte die
gemanaged werden sollen von GC_Object abgeleitet werden müssen. Wie kann ich
denn den Objectzähler in den smart pointer einbauen?

Abgesehen davon, wäre es mein Wunsch gar keinen smart pointer zu benutzen, sondern
alles in ein base object zu packen. Wenn MyObject von BaseObject abgeleitet ist,
dann ist es gemanaged. Geht das überhaupt? Ich muss doch irgendwie wissen, ob
ein pointer gerade aus dem scope läuft.

Marc
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.11.2002, 09:18 Uhr
virtual
Sexiest Bit alive
(Operator)


Eine "gute" smart Pointerclasse koennte so aussehen (nur skizziert, eine vollständige Implementierung maile ich auf Anfrage):

C++:
template<typename T>
class SmartPtr
{
     class shared_data
     {
          T* ptr;
          unsigned ref_cnt;
     };

     shared_data* data;

     static void delete_share(shared_data* data) {
         delete data->ptr;
         delete data;
     };
     static shared_data* create_share(T* ptr) {
         shared_data ret = new shared_data;
         ret->ptr = ptr;
         ret->ref_cnt = 0;
         return 0;
      };

     void assign_share(shared_data* newdata)
     {
          if (newdata) newdata->ref_cnt++;
          if (data && --data->ref_cnt==0) delete_share(data);
          data = new_data;
      };

public:
      SmartPtr() : data(0) { };
      SmartPtr(const SmartPtr& source) :data(0) { assign_share(source.data); };
      SmartPtr(T* source)  :data(0) { assign_share(source); };
      virtual ~SmartPtr()  { assign_share(0); };
      const SmartPtr& operator = (const SmartPtr& source) {
            assign_share(source.data);
            return *this;
      };
      const SmartPtr& operator = (T* source) {
            assign_share(source);
            return *this;
      };
      T* operator -> () { return data->ptr; };
      T* get()  { return data->ptr; };
      set(T* source) { assign_share(source); };
      und so weiter...
};


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: