exklusiver Konstruktorenaufruf
-
Morgen!
Mal ne recht blöde Frage:
Angenommen ich hätte folgendes Codebeispiel:#ifndef MY_EXCEPTION_H #define MY_EXCEPTION_H #include "TException.h" class TMyException : public TException { public: TMyException(char *message) : TException(message) { TException::TException("andere Fehlermeldung"); } protected: //nix private: //nix }; #endif
Warum hat denn der zweite Konstruktorenaufruf der Elternklasse TException
im Konstruktor von TMyException keine Auswirkungen auf die Fehlermeldung?
Wenn ich die Meldung ausgeben lasse, erscheint lediglich der ursprüngliche
Wert von '*message'!Grüße,
TS++
-
Hallo,
mir scheint du unterliegst hier einem klassischen Irrtum.TException::TException("andere Fehlermeldung");
Diese Zeile im Ctor von TMyException ruft *nicht* erneut den Basisklassenctor von TException auf. Das Basisklassenobjekt ist mit dem Eintreten in den Ctor von TMyException bereits vollständig erzeugt. Und da man Konstruktoren nicht explizit aufrufen kann, gibt es keine Möglichkeit den Ctor der Basisklasse nocheinmal für dieses Objekt laufen zu lassen.
In der zitierten Zeile wird lediglich ein temporäres Objekt der Klasse TException erzeugt, welches am Ende der Anweisung (also beim Semikolon) schon wieder stirbt.
Dieses temporäre Objekt hat aber *nichts* mit dem TMyException-Objekt zu tun, dass du gerade erzeugst.
-
Danke für die Antwort!
Besteht die Möglichkeit einen derartigen Effekt auf irgendeine andere
Weise doch zu erreichen?Könnte ja evtl. nützlich sein:
TClass::TClass() { //hier: Wert x berechnen TBaseClass::TBaseClass(x); }
Bei dem Beispiel würde ja zunächst der Standardkonstruktor von
TBaseClass aufgerufen, welcher in dem Beispiel hier, das unterstelle ich
einfach mal, nichts macht. Erst im Konstruktor der Kindklasse TClass
würde ich dann einen konkreten Wert x vorbereiten, der dann an den
entsprechenden Konstruktor der Basisklasse übergeben wird.
Ich wüsste jetzt nicht, wie ich einen derartigen Effekt anders erreichen
sollte!Grüße,
TS++
-
Bedeutet das jetzt, ich müsste den Code auf folgende Art und Weise
modifizieren?
(Austauschen der Meldung kann natürlich viel leichter erreicht werden!
Mir geht es jetzt mehr um die bereits genannte Kernproblemstellung)#ifndef MY_EXCEPTION_H #define MY_EXCEPTION_H #include "TException.h" class TMyException : public TException { public: TMyException(char *message) : TException(replaceMessage(message)) { //nix } protected: //nix private: char *replaceMessage(char *message) { strcpy(message,"andere Fehlermeldung"); return(message); } }; #endif
Grüße,
TS++[ Dieser Beitrag wurde am 13.04.2003 um 12:04 Uhr von TS++ editiert. ]
-
ja du bist auf den richtigen weg, nur gefält mir nicht wie du mit char * umgehst
wenn jemand z.b.throw TMyException(".");
du aber in replaceMessage "andere Fehlermeldung" rein schreibst, mal ganz davon abgesehen das man in string literare nicht reinschreiben darf
-
Das in dem von mir gewählten Beispiel das Ersetzen der Nachricht
eigentlich sinnlos ist und dass die Art und Weise, wie die Nachricht
ersetzt wird, äußerst umständlich ist, ist mir schon bewusst.
Das die Nachricht mittels einer zusätzlichen Methode ersetzt wird,
war sogar beabsichtigt.Worauf es mir in dem Beispiel ankam, war die Fähigkeit, im Konstruktor
einer Kindklasse TClass die Übergabeparameter für den Konstruktor der
Elternklasse TBaseClass zu bestimmen, mit evtl. sehr aufwändigen
Algorithmen, und diese Parameter an den Elternkonstruktor zu übergeben.Bei folgendem Fall muss man sich ja keine weiteren Gedanken machen:
TClass::TClass() : TBaseClass(1) { //nix }
Hier kann ich ja bereits beim Entwickeln genau fessetzen, mit welchem Parameter
der Elternkonstruktor versehen wird.Oder ich lasse durch den Anwendungsentwickler festlegen, welcher Wert in
den Elternkonstruktor wandern soll:TClass::TClass(int val) : TBaseClass(val) { //nix }
==> nur falls der zu übergebende Parameter durch TClass festgesetzt werden soll,
der Anwendungsentwickler demzufolge keinen Einfluss auf den Wert besitzt, und
sich der Parameter nur mit einem vielleicht recht aufwändigen Algorithmus ermitteln lässt, nützen mir die oben genannten Ansätze natürlich nichts mehr!Eine Lösung wäre, wie ich jetzt weiss, ja z.B. folgendes:
TClass::TClass() : TBaseClass(computeParam()) <param> TClass::computeParam() { //hier: Parameter berechnen return(<param> ); }
Ist, aus meiner Sicht, natürlich etwas umständlich, für den Konstruktorenaufruf
eigene Methoden zu entwickeln. Darum kam ich zu dem Irrglauben, dass das Problem
auch folgendermaßen gelöst werden könnte:TClass::TClass() //zuerst Standardkonstruktor von TBaseClass, der nichts macht { //hier: Parameter berechnen TBaseClass::TBaseClass(<param> ); }
Und exakt das war mein Problem!
Grüße,
TS++[ Dieser Beitrag wurde am 13.04.2003 um 14:14 Uhr von TS++ editiert. ]