Initialisation - Vererbung oder Member?
-
Ich habe eine Klasse die bestimmte Initialisierungsaufgaben übernehmen soll:
class Init { public: Init () { if(!objcntr) // Init ++objcntr; } ~Init () { --objcntr; if(!objcntr) // Deinit } private: static unsigned long int objcntr; };
Nun soll - egal ob ein Objekt A, B oder C erstellt wird wenn es sein muss diese Initialisierung durchgeführt werden.
Soll ich dazu:
a) Init public an A, B und C vererben (Schnittstelle brauch ich doch gar nicht und A, B und C sind doch sicher kein Init...)
b) Init private an A, B und C vererben (Hmm, hab noch nie was private vererbt *g*)
c) Init als Member ("Hat ein" Initialisierungsobjekt? Naja auch nicht 100% logisch)
Wie macht mans richtig?
MfG SideWinder
-
Counting Objects in C++
Leider gibt der Artikel gibt keine vollständige Antwort auf deine Frage (es geht nur um die reine Auszählung).
-
Kopiert wird nichts, recht viel mehr neue Information bringt der Artikel daher leider nicht
MfG SideWinder
-
SideWinder schrieb:
a) Init public an A, B und C vererben (Schnittstelle brauch ich doch gar nicht und A, B und C sind doch sicher kein Init...)
Nope. Dtor von Init ist public und nicht virtuell -> Neben der Semantischen-Problematik bekommst du gleich noch eine technische.
b) Init private an A, B und C vererben (Hmm, hab noch nie was private vererbt *g*)
Kommt drauf an.
c) Init als Member ("Hat ein" Initialisierungsobjekt? Naja auch nicht 100% logisch)
Kommt drauf an.
Prinzipiell solltest du wenn möglich "hat ein" bzw. "wird implementiert durch" über Layering (Möglichkeit c) implementieren.
Brauchst du aber Zugriff auf virtuelle Methoden (hier nicht der Fall), protected Methoden (hier nicht der Fall), willst du von der Empty-Base-Optimization profitieren oder ist es nötig, dass dein Sub-Objekt *vor* einer anderen Basisklasse konstruiert wird, dann musst du private-Vererbung verwenden.
-
Ja, die Init-Klasse kann ich ja im Falle von Vererbung sehr schnell virtuell werden lassen
Also, da es wichtig ist, dass diese Init-Klasse _vor_ allen anderen Membern der Klasse fertig initialisiert wurde werde ich private-Vererbung nehmen.
MfG SideWinder
-
SideWinder schrieb:
Ich habe eine Klasse die bestimmte Initialisierungsaufgaben übernehmen soll:
init ist also sehr wichtig. wie wichtig ist deinit und ist es erwünscht, daß deinit sofort zuschlägt oder erst am programmende.
Nun soll - egal ob ein Objekt A, B oder C erstellt wird wenn es sein muss diese Initialisierung durchgeführt werden.
Soll ich dazu:
a) Init public an A, B und C vererben (Schnittstelle brauch ich doch gar nicht und A, B und C sind doch sicher kein Init...)
b) Init private an A, B und C vererben (Hmm, hab noch nie was private vererbt *g*)
c) Init als Member ("Hat ein" Initialisierungsobjekt? Naja auch nicht 100% logisch)
Wie macht mans richtig?mit d)
hau "static Init init;" in den Konstruktor der entsprechenden klassen. (wende ich mit freude selber an).mit e)
hau Init& in die parameterliste des Konstruktors der entsprechenden klassen und der aufrufer wird schon dafür soren, daß ein Init-Obekt existiert. (wende ich mit freude auch selber an).kann absolut nicht sagen, wie man's ricgtig macht, solange ich nicht genug über das problem weiß.
-
Am Programmende ist es mir zu spät, womit die static-Variante wohl ausfällt. Init ist zwar um einiges wichtiger als Deinit (da Deinit im Notfall das OS für mich übernehmen würde). Aber eben deswegen deinitialisiere ich ja selbst -> damit es bereits vorher passiert (Resourcen sparen).
Zur Referenzlösung noch eine Frage, was passiert hier:
{ Init init; Klasse* obj = new Klasse(init); } // Was ist hier mit init los?
MfG SideWinder
-
SideWinder schrieb:
Am Programmende ist es mir zu spät, womit die static-Variante wohl ausfällt. Init ist zwar um einiges wichtiger als Deinit (da Deinit im Notfall das OS für mich übernehmen würde). Aber eben deswegen deinitialisiere ich ja selbst -> damit es bereits vorher passiert (Resourcen sparen).
war halt aus der frage nicht ersichtlich. sowas wie Init hab ich für sachen wie die winsockdll, die soll gar nicht immer wieder sterben und neu erstehen, nur weil ich den letzten socket auf- und zumache.
Zur Referenzlösung noch eine Frage, was passiert hier:
{ Init init; Klasse* obj = new Klasse(init); } // Was ist hier mit init los?
da passiert dann vermutlich irgendwas böses. die referenzlösung ist auch eher für ne winsockdll, die länger lebt als alle sockts, die mitsamt ihrem container in nem inneren block gebaut werden.
oder für sachen wie File f("bla.txt"); LineReader lr(f); ... nebst der feststellung, daß files und linereaders nie auf dem freispeicher landen.
ich hab aber auch vor, das mit freispeichersachen auszuprobieren, dann gehört's aber eher in die abteilung experimentelles programmieren.Also, da es wichtig ist, dass diese Init-Klasse _vor_ allen anderen Membern der Klasse fertig initialisiert wurde werde ich private-Vererbung nehmen.
ok.
muß es wirklich vor _allen_ members sein? oder nur vor bestimmten? muss init evtl in bestimmte members rein?
-
1. Es geht darum, dass eine bestimmte Datei (denk dabei nicht sofort an eine Datei im Dateisystem) geladen sein muss *bevor* bestimmte Klassen (3 an der Zahl) instanziert werden - die rufen im Konstruktor bereits Funktionen von Membern auf die wiederrum fehlschlagen wenn die Datei noch nicht geladen wurde.
2. Die Datei muss immer geladen sein. Die Informationen in dieser Datei werden von anderen Threads verändert und dürfen nicht unaktuell zwischengespeichert werden. Also erst entladen wenn sie nicht mehr benötigt werden (immer neu aufmachen und auf Veränderungen prüfen wurde als Performance-Killer abgelehnt).
3. Wenn sie hingegen nicht mehr benötigt werden dann möglichst schnell weg damit weil die Sache sehr resourcenfressend ist.
MfG SideWinder