[Gelöst]Shared_Ptr Klasse
-
Hallo, ich habe versucht die Shared_Ptr Klasse selbst zu definieren jedoch erhalte ich eine Fehlermeldung:
Ausnahmefehler bei 0x013A3FA5 in Projekt6.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000
HasPtr.h
#ifndef HASPTR_INCLUDED #define HASPTR_INCLUDED #include <string> #include <iostream> using namespace std; class HasPtr { public: // Konstruktoren HasPtr() = default; HasPtr(const string&); HasPtr(const HasPtr&); HasPtr& operator=(const HasPtr&); // Destruktor ~HasPtr(); // Ausgabe Attribute void ausgabe() const; private: // Attribute int* benutzer; string* name; }; // Konstruktor HasPtr::HasPtr(const string& Name) : name(new string(Name)), benutzer(new int(1)) { } // Kopierkonstruktor HasPtr::HasPtr(const HasPtr& HObjekt) { if (&HObjekt != this) { ++*HObjekt.benutzer; if (--*benutzer == 0) { delete benutzer; delete name; } benutzer = HObjekt.benutzer; name = HObjekt.name; } } // Zuweisungskonstruktor HasPtr& HasPtr::operator=(const HasPtr& HObjekt) { if (&HObjekt != this) { ++*HObjekt.benutzer; if (--*benutzer == 0) { delete benutzer; delete name; } benutzer = HObjekt.benutzer; name = HObjekt.name; } return *this; } // Destruktor HasPtr::~HasPtr() { if (--*benutzer == 0) { delete benutzer; delete name; } } // Ausgabe void HasPtr::ausgabe() const { std::cout << "\n---------------------------------------------\n"; std::cout << "Benutzer Name:" << *name << std::endl; std::cout << "Benutzer Zaehler:" << *benutzer << std::endl; std::cout << "---------------------------------------------\n"; } #endif
Main.cpp
#include "HasPtr.h" int main() { HasPtr MainObjekt("Test 1"); HasPtr NebenObjekt1(MainObjekt); HasPtr NebenObjekt2(MainObjekt); MainObjekt.ausgabe(); }
-
Wenn du in der main in Zeile 6 den Kopierkonstruktor aufrufst, welchen Wert hat dann benutzer in Zeile 39?
Die Frage soll dazu dienen dir Gedanken darüber zu machen, was du da in 39 bis 43 eigentlich machst und inwiefern das notwendig ist.
-
Einen undefinierten, vielen Dank.
Edit: Ich glaube das ich entweder den Attrubuten Startwerte zuweisen muss(in der Klasse) oder der Kopierkonstruktor ein name und benutzer der klasse neu anlegen muss.
-
TemplateQ schrieb:
Edit: Ich glaube das ich entweder den Attrubuten Startwerte zuweisen muss(in der Klasse) oder der Kopierkonstruktor ein name und benutzer der klasse neu anlegen muss.
Wieso musst du überhaupt den alten Count dekrementieren? Die Klasse kann ja zu dem Zeitpunkt keine Resource besitzen, also musst du auch nichts freigeben. Alles was du machen musst ist die Pointer vom anderen Objekt herüber zu kopieren und den gemeinsem count-Pointer erhöhen.
Das du std::string nicht mit new anlegen musst ist dir aber hoffentlich bewusst?
-
[quote="Nathan"]
TemplateQ schrieb:
Das du std::string nicht mit new anlegen musst ist dir aber hoffentlich bewusst?
Das Attribut name ist ein Zeiger auf ein string Objekt und Zeiger muss man mit new anlegen oder habe ich da etwas falsch verstanden?
-
[quote="TemplateQ"]
Nathan schrieb:
TemplateQ schrieb:
Das du std::string nicht mit new anlegen musst ist dir aber hoffentlich bewusst?
Das Attribut name ist ein Zeiger auf ein string Objekt und Zeiger muss man mit new anlegen oder habe ich da etwas falsch verstanden?
(nitpicky: new "legt keinen Zeiger an" sondern ein Objekt und liefert dann einen Zeiger darauf zurück.)
Aber warum überhaupt Zeiger als Member? * enfernen, new entfernen und glücklicher sein als vorher.
Das ist kein Java, man kann sachen auch ohne new erzeugen.
-
Uch habe einen Zeiger als member damit bei änderungen auch die Objekte die auf die Klasse zeigen geupdatet werden, sonst wird doch rein theoretisch nur die Kopie übergeben.
-
Ein Zeiger ist schon ok. Aber fasse besser beide Verwaltungsdaten zusammen:
class HasPtr { public: // Konstruktoren HasPtr() = default; HasPtr(const string&); HasPtr(const HasPtr&); HasPtr& operator=(const HasPtr&); // Destruktor ~HasPtr(); // Ausgabe Attribute void ausgabe() const; private: struct SharedData { int count; string name; }; SharedData *ptr; };
-
Guck dir das Copy&Swap Idiom an.
Das passt hier perfekt.
-
Vielen Dank, das werde ich tun!