Klassen "dynamisch" erstellen
-
Hallo,
ich schreibe derzeit eine art adressbuch. dazu habe ich mir eine klasse "person" erstellt. in dieser klasse sind nun email-addresse, telefonnummer etc. gespeichert. nun möchte ich, um das adressbuch besser verwalten zu können folgendes realisieren: beim anlegen eines neuen benutzers soll eine neue klasse "person" erstellt werden. d.h. hinter jedem eintrag meines adressbuchs ist eine klasse "person" am werkeln. mein problem ist nun, wie erstelle ich diese klasse zu laufzeit?!ich habe hier im forum schon was über templates gelesen, war mir aber nicht ganz sicher ob das auch mein problem betrifft, weil ich es nicht wirklich verstanden habe. falls es also doch damit zusammenhängt, würde ich mich freuen, wenn jemand einen link o.ä. zu einer kleinen einführung posten würden.
ciao, cypoc
-
cypoc schrieb:
Hallo,
ich schreibe derzeit eine art adressbuch. dazu habe ich mir eine klasse "person" erstellt. in dieser klasse sind nun email-addresse, telefonnummer etc. gespeichert. nun möchte ich, um das adressbuch besser verwalten zu können folgendes realisieren: beim anlegen eines neuen benutzers soll eine neue klasse "person" erstellt werden. d.h. hinter jedem eintrag meines adressbuchs ist eine klasse "person" am werkeln. mein problem ist nun, wie erstelle ich diese klasse zu laufzeit?!Ich seh nicht die Notwendigkeit, da eine Klasse zu erstellen. Meinst du nicht vielleicht eine Instanz zu erstellen? BTW kann man Klassen in C++ nicht zur Laufzeit erstellen.
templates haben damit übrigens nicht das geringste zu tun.
-
Du kannst Objekte deiner Klasse zur Laufzeit erstellen
-
genau das mein ich.
was die fachbegriffe angeht, bin ich nicht so firm...aber es fällt mir schon mal ein stein vom herzen, dass das nix mit templates zu tun hat.
ciao, cypoc
-
Cypoc* pCypoc = new Cypoc;
-
... weißt du den wie?
Wenn du am Anfang noch nciht weißt, wieviele Personen du verwalten musst, dann würde ich dir std::list empfehlern. HAt aber wa smit Templates zu tun, ist aber ganz ganz einfach: oder std::vector
// INitialiiseren: std::list<CPerson> PersonenListe; CPerson Person; PersonenListe.push_back(Person)
Beschäftgie dich mal mit list oder Vecotr, das ist ganz einfach zu implementieren
Gruß, Maxi
-
na das ging aber fix!
wäre nett wenn du das noch ein bissl erklären könntest. so wie ich das bis jetzt sehe, erzeuge ich bei jedem hinzufügen eines benutzers ein objekt meiner klasse person namens pCypoc?! wenn ich nun drei benutzer hinzufüge, heißen deren objekte dann nicht alle pCypoc???bis dann!
-
ha! wusste ich doch, hat was mit templates zu tun! genau das ist mein problem, ich weiß nicht wie viele adressen da kommen werden.
ciao, cypoc
-
nein, dein Problem allein hat nichts mit templates zu tun. nur std::list/std::vector/std::deque sind ein templates. diese drei klassen sind sogenannte container, d.h. sie können objekte verwalten, egal wie viele.
such dir ein gutes buch, online tutorial, etc. und informier dich am besten über sie
-
ALternative währe sich selbst ne verkettete Liste zu schreiben. Ist nur etwas aufwändiger als vektor und list.
-
std::list ist ja echt geil!
eine frage hab ich noch: wenn ich mit erase einen listeneintrag lösche, dann wird mein objekt doch nicht zerstört, oder?! ich hab das mal ausprobiert, der destruktor wurde jedenfalls nicht aufgerufen. wenn ich nun, mehrere tausend objekte in meiner liste hab und vor dem beenden meines programms einfach die liste leere, dann kann das doch fatale folgen haben, oder?!also der tip mit list und co hat's echt gebracht
vielen DANK!
ciao, cypoc
-
Die Objekte sind nur Teil einer Liste, werden imho somit beim Löschen nicht physisch zerstört. Bei einer selbstgeschriebenen verketteten Liste könntest du so eine Funktion allerdings einbauen.
-
jo, ok. dachte ich mir schon in der art. war mir aber nicht ganz sicher.
danke nochmal @ all.
ciao
-
cypoc schrieb:
std::list ist ja echt geil!
eine frage hab ich noch: wenn ich mit erase einen listeneintrag lösche, dann wird mein objekt doch nicht zerstört, oder?!Doch.
ich hab das mal ausprobiert, der destruktor wurde jedenfalls nicht aufgerufen.
Dann hattest du keine Objekte mit Destruktoren im Container, sondern vielleicht Pointer auf Objekte? Du mußt bedenken, der Container ist im wesentlich strohdumm, und behandelt alle Typen gleich. Für ihn ist alles ein T, ob das jetzt ein Pointer ist oder ein anderer Container, spielt keine Rolle.
Beim erase wird das Element gelöscht, d.h. sein Destruktor wird aufgerufen und der Speicher freigegeben. Nur hat ein Zeiger als primitiver Datentyp keinen Destruktor! Das heißt, es passiert nichts.
Es darf auch nichts passieren. Woher soll der Container denn wissen, dass du in ihm nur Zeiger auf Heap-Objekte speicherst, und dass er der einzige Besitzer dieser Zeiger ist?
Schlussfolgerung aus dem ganzen: Wenn du Zeiger im Container speichern willst, musst du dich selbst um das Managen der zugehörigen Objekte kümmern, sprich von Hand deleten.
-
simon.phoenix schrieb:
Die Objekte sind nur Teil einer Liste, werden imho somit beim Löschen nicht physisch zerstört.
Doch, werden sie.
-
es sind zeiger...
ich vergaß das zu erwähnen.
aber damit wäre meine frage ja beantwortet.
-
Statt rohen Zeigern boost::shared_ptr<T> (www.boost.org) zu verwenden, um ihnen Wertsemantiken "anzuhängen", ist IMHO wesentlich bequemer und sicherer als die Variante mit manuellen deletes, und man muss sich praktisch keine Gedanken mehr um Exceptions machen.
std::list<boost::shared_ptr<T> > list; boost::shared_ptr<T> ptr = new T; list.push_back(ptr); // Wenn push_back wirft, wird *ptr freigegeben list.clear(); // Hier wird auch alles korrekt freigegeben
-
hört sich nicht schlecht an.
werd mir das mal anschauen!
danke!ciao