Stringklasse mit Reference Counting (aus More Effective C++)



  • Ist doch easy 😉

    SirLant schrieb:

    class String {
    	private:
    		struct StringValue {
    			int refCount; // Referenzzähler
    			char *data; // Der eigentliche String
    			StringValue (const char *initValue);
    			~StringValue ();
    		};
    		
    		StringValue *value;
    	public:
    		String (const char *initValue = "");
    		String (const String &rhs);
    };
    
    String::String (const char *initValue) //char*, kein RC möglich
    	: value (new StringValue (initValue))
    {}
    
    String::String (const String &rhs) //ah, eine kopie - also RC
    	: value (rhs.value) { //zeiger merken
    //man beachte: KEINE Kopie, nur zeiger merken
    	
    		++value->refCount; //refcount erhöhen
    }
    
    String::~String () {
    	
    	if (--value->refCount == 0) //RC verringern
    		delete value; //wenn leer - dann adieu
    }
    
    String::StringValue::StringValue (const char *initValue) //ein neues objekt
    	: refCount (1) { //RC muss 1 sein ;)
    	//string anlegen
    		data = new char[strlen (initValue) + 1];
    		strcpy (data, initValue);
    }
    
    String::StringValue::~StringValue () {
    	delete [] data;
    }
    

    ich hoffe es ist jetzt klar?



  • Nein davon steht da nichts, ich ging davon aus, der ruft den built-in Zuweisungsoperator auf.
    Aber auch, wenn er den Copy Ctor aufruft, wie kommt es da zu dem kopieren der Adresse
    von s1 in s2?
    Beim Aufruft des Copy Ctors wird ja folgendes gemacht:
    Initialisierungsliste: value (rhs.value)
    -Aufruf des StringValue Ctors und dieser kopiert den string ja in den mit new
    allokierten Speicherbereich und setzt refCount auf 1.
    -Copy Ctor von String erhöht, dann den Referenzzähler noch um 1 wodurch er auf 2 steht

    Wo wird hier, denn die Adresse von s1 an s2 zugewiesen?

    Edit:
    Shade, die Zeile die für dich Sonnenklar ist verstehe ich nicht:

    : value (rhs.value) { //zeiger merken
    //man beachte: KEINE Kopie, nur zeiger merken
    

    Wie kann er sich hier den Zeiger einfach merken ?

    Edit:
    Achso ich glaub ich habe es, hier wird der built-in Copy Ctor von StringValue
    aufgerufen der einfach eine Flache Kopie erzeugt, richtig ?



  • SirLant schrieb:

    Nein davon steht da nichts, ich ging davon aus, der ruft den built-in Zuweisungsoperator auf.

    siehe Humes FAQ - direct initialization versus copy initialization

    Aber auch, wenn er den Copy Ctor aufruft, wie kommt es da zu dem kopieren der Adresse
    von s1 in s2?
    Beim Aufruft des Copy Ctors wird ja folgendes gemacht:
    Initialisierungsliste: value (rhs.value)
    -Aufruf des StringValue Ctors und dieser kopiert den string ja in den mit new
    allokierten Speicherbereich und setzt refCount auf 1.
    -Copy Ctor von String erhöht, dann den Referenzzähler noch um 1 wodurch er auf 2 steht

    schau dir den code mit meinen kommentaren mal an - dann sollte es klar werden.

    beachte: value ist ein Zeiger auf StringValue Objekt - deshalb ist value(rhs.value) nur eine Zeiger-Kopiererei.

    Die StringValue Objekte sind die, die geshared werden 😉



  • SirLant schrieb:

    Achso ich glaub ich habe es, hier wird der built-in Copy Ctor von StringValue
    aufgerufen der einfach eine Flache Kopie erzeugt, richtig ?

    nein, sowohl value als auch rhs.value sind nur Zeiger - es wird also der Zeiger kopiert.



  • SirLant schrieb:

    Wie kann er sich hier den Zeiger einfach merken ?

    Edit:
    Achso ich glaub ich habe es, hier wird der built-in Copy Ctor von StringValue
    aufgerufen der einfach eine Flache Kopie erzeugt, richtig ?

    es wird KEIN Ctor aufgerufen, wie denn auch? Es ist ein Zeiger! Die Kopie des Zeigers der auf die StringValue Struktur zeigt, wird gespeichert.



  • Und durch was wird dieser kopiert? Ist das einfach ein value = rhs.value; ?



  • SirLant schrieb:

    Und durch was wird dieser kopiert? Ist das einfach ein value = rhs.value; ?

    Keine Ahnung was du meinst.

    Ich glaube du hast gerade ne kleine Denkblockade. Am besten du lässt das Thema mal kurz in Ruhe und schaust dir den Code in einer Stunde oder so nochmal an.

    Denn ich weiss, dass du genug wissen hast, um den Code zu verstehen - also mach mal ne kleine Pause, dann siehst du wieder den Wald (trotz der Bäume)

    Und nicht vergessen: value ist nur ein Zeiger, somit ist value=rhs.value eine Zuweisung von Zeiger an Zeiger.



  • Hallo,

    SirLant schrieb:

    Und durch was wird dieser kopiert? Ist das einfach ein value = rhs.value; ?

    richtig, über die "initializer list" des Copy-Konstruktors:

    [cpp]
    String::String (const String &rhs)
    : value (rhs.value)
    [/cpp]

    Initialisierung über "initializer list".

    MfG



  • Jetzt hat sich die Blockade gerade gelöst, ist ja eigentlich total logisch 🤡

    Danke 🙂



  • SirLant schrieb:

    Und durch was wird dieser kopiert? Ist das einfach ein value = rhs.value; ?

    sei mir nicht böse, aber bevor man Mayers liest, sollte man schon wissen, was ein Element-Initialisierer ist.


Anmelden zum Antworten