RAII mit Smart Pointer



  • Dieser shared_ptr benutzt ja non-intrusive ref counting. Kann ich mir mal irgendwo eine Beispielimplementierung von shared_ptr anschauen? Würde gern mal sehen, wie das mit dem Ref Counter bei non-intrusive funktioniert (Will mir aber nicht den original boost Code anschauen. Der is zu komplex und optimiert. Mir gehts nur ums Prinzip)



  • Also "Modern C++ Design" von Alexandrescu hat ein Kapitel über Smart Pointer.

    Online gibts bestimmt auch gute Erklärungen, aber müsste ich auch zuerst suchen. 😉



  • Du hast neben dem Speicherbereich für das Objekt einen zweiten Speicherbereich, der ebenfalls geteilt wird und nur eine Zahl (Anzahl der Referenzen) mit Initialwert 1 enthält. Bei der Kopie eines shared_ptr s wird diese Zahl erhöht. Im Destruktor wird die Zahl erniedrigt, und falls sie 0 erreicht (letzter shared_ptr wird zerstört), wird das Objekt zerstört und freigegeben.



  • Könnte jemand vielleicht schnell ein bißchen Code einer möglichst simplen shared_ptr Implementierung schreiben? Also nur das Notwendigste (Member, Ctor, Dtor und operator= denk ich mal)



  • Du hast Glück, dass ich sowas schon mal gemacht und sogar den Thread wiedergefunden habe 🕶
    http://www.c-plusplus.net/forum/262675



  • Etwa so, denke ich:

    template<typename t>
    class shared_ptr {
    	public:
    		shared_ptr() : myObject(NULL), myCounter(NULL) {
    		}
    
    		shared_ptr( t* Object ) : myObject(Object), myCounter(new int(1)) {
    		}
    
    		shared_ptr( const shared_ptr& Other ) {
    			take( Other );
    		}
    
    		~shared_ptr() {
    			release();
    		}
    
    		shared_ptr& operator=( const shared_ptr& Other ) {
    			release();
    			take( Other );
    		}
    
    	protected:
    		void take( const shared_ptr& Other ) {
    			myObject = Other.myObject;
    			myCounter = Other.myCounter;
    			if ( myObject )
    				++*myCounter;
    		}
    
    		void release() {
    			if ( ! myObject )
    				return;
    			if ( --*myCounter == 0 ) {
    				delete myObject;
    				delete myCounter;
    			}
    			myObject = NULL;
    			myCounter = NULL;
    		}
    
    	private:
    		t* myObject;
    		int* myCounter;
    };
    


  • Vielen Dank euch beiden! 👍

    @Nexus: Fehlt bei deinem operator= nicht noch eine Dekrementierung von m_refcount? So wie ich das sehe setzt du doch nur die Member von this auf die Werte vom übergebenen rhs, aber du dekrementierst nirgends den Wert von this->m_refcount, oder?



  • RaderZweite schrieb:

    @Nexus: Fehlt bei deinem operator= nicht noch eine Dekrementierung von m_refcount?

    Nein, er macht copy&swap.

    Da hat er im dtor das decrement und im ctor das increment 😉



  • Der Code ist schon recht alt (war er schon zum Zeitpunkt des Posts), ich hab ihn nur mal geschrieben, um etwas herumzuexperimentieren und die Hintergründe besser zu verstehen. Eingesetzt wurde er nie, wirklich getestet auch nicht.

    Der Schnipsel entspricht auch nicht 1:1 dem Originalcode, ich habe dazumals einige Dinge vereinfacht (und auch kleinere Schreibfehler gemacht :)).



  • Nexus schrieb:

    scoped_ptr ist im Prinzip der RAII-Smart-Pointer. Er macht nichts anderes als am Ende des Scopes automatisch delete aufzurufen.

    Im Zusammenhang damit sollte man evtl. auch den unique_ptr erwähnen.
    unique_ptr ist im Prinzip der RAII-Smart-Pointer ab C++0x.


Anmelden zum Antworten