Thread View: de.comp.lang.c++
6 messages
6 total messages
Started by Stephen Friedrich
Wed, 02 Aug 1995 13:45
Globale Objekte, exception aus Konstruktor
Author: Stephen Friedrich
Date: Wed, 02 Aug 1995 13:45
Date: Wed, 02 Aug 1995 13:45
104 lines
2991 bytes
2991 bytes
Hallo Leute,
weiss jemand eine Loesung fuer folgendes Problem?
Ein Objekt ist global deklariert. Der Konstruktor dazu
loest eine Exception aus. Wie kann ich diese abfangen?
Das ist IMO ein generelles C++-Problem. Mir stellt es sich
unter SunOS 4.1.2 auf einer SparcStation mit gcc 2.6.3.
Also:
//--------- Except.cxx ---------------------------------
class Except {};
class Global {
public:
Global(void) { throw Except(); };
};
Global aGlobal;
int main(int argc, char* argv[]) {};
//-------------------------------------------------------`
Compiliert mit
g++ -g -fhandle-exceptions -o Except Except.cxx
bewirkt die Ausfuehrung natuerlich nur die Ausgabe von
"Abort".
Ich habe ausprobiert einen terminate()-Handler zu
installieren, der innerhalb eines try{} ein rethrow
macht.
Das scheint jedoch nicht moeglich zu sein.
Folgendes fuehrt nach einmaliger Ausgabe von "rethrow!"
zu einer Endlosschleife innerhalb der gcc-Laufzeit-
Bibliothek:
//--------- Except.cxx ---------------------------------
#include <iostream.h>
class Except {};
typedef void(*PFV)();
PFV set_terminate(PFV);
PFV old;
void rethrow(void) {
cout << "rethrow!" << endl << flush;
set_terminate(old);
try {
throw;
}
catch(Except a) {
cout << "TestException!" << endl << flush;
abort();
};
};
class CatchException {
public:
CatchException();
};
CatchException::CatchException (void) {
old = set_terminate(&rethrow);
};
CatchException aCatchException;
class Global {
public:
Global(void) { throw Except(); };
};
Global aGlobal;
int main(int argc, char* argv[]) {};
//-------------------------------------------------------
Es ist sicher im allgemeinen nicht sinnvoll Objekte global
zu deklarieren. Einige Application-Frameworks verlangen das
jedoch fuer bestimmte Objekte, eben um noch vor main()
Initialisierungen zu machen.
Im uebrigen interessiert mich generell eine Loesung.
C++ scheint kein Konzept zu haben, das nicht irgendwo Luecken
oder Unsauberkeiten hat...
Waere dafuer nicht die Moeglichkeit sinnvoll globale
catch()-Funktionen zu schreiben?
----------------------------------------------------------
Stephen Friedrich, Mettlerkampsweg 2, 20535 Hamburg
email : 1friedri@informatik.uni-hamburg.de
Stephen.Friedrich@Hamburg.Netsurf.de
Compuserve: 100440,3434
Fax : +49 40 218418
Re: Globale Objekte, exception aus Konstruktor
Author: Ralf W. Stephan
Date: Fri, 04 Aug 1995 10:06
Date: Fri, 04 Aug 1995 10:06
12 lines
765 bytes
765 bytes
Stephen Friedrich writes: > Ein Objekt ist global deklariert. Der Konstruktor dazu > loest eine Exception aus. Wie kann ich diese abfangen? > Das ist IMO ein generelles C++-Problem. Nein, das ist schlechtes Design. Globale Objekte sind Bad Things [tm] in C++. Benutze lokale (in main()) Objekte und übergebe sie als Referenzen an die Objekte, die es brauchen. ralf
Re: Globale Objekte, exception aus Konstruktor
Author: Ullrich von Bassewitz
Date: Fri, 04 Aug 1995 20:33
Date: Fri, 04 Aug 1995 20:33
31 lines
1616 bytes
1616 bytes
Ralf W. Stephan (ralf@ark.franken.de) wrote: > Stephen Friedrich writes: > > Ein Objekt ist global deklariert. Der Konstruktor dazu > > loest eine Exception aus. Wie kann ich diese abfangen? > > > Das ist IMO ein generelles C++-Problem. > > Nein, das ist schlechtes Design. Globale Objekte sind Bad Things [tm] > in C++. Benutze lokale (in main()) Objekte und übergebe sie als > Referenzen an die Objekte, die es brauchen. Wieso ist das schlechtes Design? Die C++ I/O-Streams benutzen z.B. globale Objekte um sicherzustellen, dass cin, cout etc. bereits vor dem Aufruf von main() geoeffnet werden. Ist das auch schlechtes Design? Das soll kein Flame sein, ich will bloss wissen, woran Du hier "schlechtes Design" festmachst. Wenn ich mich recht erinnere gibt es irgendwo einen Satz von Stroustrup, der fuer aehnliche Probleme wie das eben genannte, globale Objekte als "elegante Loesung" empfiehlt... Ist das urspruengliche Problem nicht eher ein Manko von C++? (Ein Grund fuer nochmal eine Spracherweiterung?) Neugierig Uz -- Ullrich von Bassewitz uz@ibb.schwaben.com
Re: Globale Objekte, exception aus Konstruktor
Author: Ralf W. Stephan
Date: Sat, 05 Aug 1995 13:14
Date: Sat, 05 Aug 1995 13:14
39 lines
2277 bytes
2277 bytes
Ullrich von Bassewitz writes: > Ralf W. Stephan (ralf@ark.franken.de) wrote: > > Stephen Friedrich writes: > > > Das ist IMO ein generelles C++-Problem. > > Nein, das ist schlechtes Design. Globale Objekte sind Bad Things [tm] > > in C++. Benutze lokale (in main()) Objekte und übergebe sie als > > Referenzen an die Objekte, die es brauchen. > Wieso ist das schlechtes Design? Die C++ I/O-Streams benutzen z.B. globale > Objekte um sicherzustellen, dass cin, cout etc. bereits vor dem Aufruf von > main() geoeffnet werden. Ist das auch schlechtes Design? Weiß ich nicht, aber Du wirst mir sicher zustimmen, wenn ich sage, daß das ein Sonderfall ist, bzw. wann brauchst Du schon mal ein Objekt, bevor main() startet? > Das soll kein Flame sein, ich will bloss wissen, woran Du hier "schlechtes > Design" festmachst. An nichts Bestimmtem. Ich habe den Fehler gemacht, den Originalartikel des Autors nicht zu Ende zu lesen, wo er nämlich selber schreibt, daß er globale Objekte nur deswegen verwendet, weil er bestimmte application frameworks benutzt. Sorry. Bestimmte Kodierungsstile werden oft deswegen als Bad Design bezeichnet, weil sie letztendlich zu fehleranfälligem Code führen. Globale Objekte werden oft mit einer init()-Memberfunktion initialisiert (anstatt im Konstruktor), weil zB argc,argv erst später zur Verfügung steht. Ebenso ist die Einkapselung nicht mehr gegeben, wenn globale Strukturen überall im Code vorkommen; das gilt doch auch schon für C. Und ich persönlich finde es einfach schöner... > Ist das urspruengliche Problem nicht eher ein Manko von C++? (Ein Grund fuer > nochmal eine Spracherweiterung?) Bei den Exceptions wurde ja noch nicht viel (?) verändert. Vielleicht kommt ja noch eine Handler-Funktion dazu, für solche Fälle. ralf
Re: Globale Objekte, exception aus Konstruktor
Author: Ullrich von Bassewitz
Date: Sun, 06 Aug 1995 14:09
Date: Sun, 06 Aug 1995 14:09
65 lines
3579 bytes
3579 bytes
Ralf W. Stephan (ralf@ark.franken.de) wrote: > Ullrich von Bassewitz writes: > > Ralf W. Stephan (ralf@ark.franken.de) wrote: > > > Nein, das ist schlechtes Design. Globale Objekte sind Bad Things [tm] > > > in C++. Benutze lokale (in main()) Objekte und übergebe sie als > > > Referenzen an die Objekte, die es brauchen. > > Wieso ist das schlechtes Design? Die C++ I/O-Streams benutzen z.B. globale > > Objekte um sicherzustellen, dass cin, cout etc. bereits vor dem Aufruf von > > main() geoeffnet werden. Ist das auch schlechtes Design? > > Weiß ich nicht, aber Du wirst mir sicher zustimmen, wenn ich sage, daß > das ein Sonderfall ist, bzw. wann brauchst Du schon mal ein Objekt, bevor > main() startet? Die haeufigste Anwendung fuer globale Objekte sind Initialisierungen fuer bestimmte Module oder Objekte (zumindest ist das bei mir so und das habe ich auch bei Stroustrup so rausgelesen). Globale Objekte bieten sich immer dann an, wenn Du bestimmte Dinge durch- fuehren willst, bevor main() startet. Bei einer Klassenblibliothek von mir sind das z.B. Registrierungen fuer persistente Objekte. Haette nicht jedes Modul ein oder mehrere statische Objekte, die die notwendigen Registrierungen durchfuehren, dann muesste der Programmierer das in jedem Programm zu Fuss durch Aufrufe von einzelnen Funktionen machen - und das waere bei der Vielzahl der persistenten Objekte eine ermuedende und auch sehr fehler- anfaellige Geschichte. Das eine Initialisierung nicht durchgefuehrt wurde merkst Du naemlich in dem Fall erst recht spaet bzw. u.U. in der Testphase ueberhaupt nicht. Bei der Verwendung globaler Objekte zur Initialisierung eruebrigt sich das. In meinen Augen ist das eine sehr elegante Moeglichkeit... > Bestimmte Kodierungsstile werden oft deswegen als Bad Design bezeichnet, > weil sie letztendlich zu fehleranfälligem Code führen. Globale Objekte > werden oft mit einer init()-Memberfunktion initialisiert (anstatt im > Konstruktor), weil zB argc,argv erst später zur Verfügung steht. Ich habe bei mir kein einziges globales Objekt, das mit einer Init() Funktion initialisiert wird. Das was Du angibst (Zugriff auf argc und argv) ist einer der wenigen denkbaren Faelle, wo das notwendig sein sollte, dann aber liegt das Problem woanders, naemlich in der Trennung von Instantiierung und Initialisierung, nicht bei den globalen Objekten... Und wie oben genannt, waere (zumindest bei meiner Bibliothek) der _Verzicht_ auf globale Objekte der eindeutig fehleranfaelligere und umstaendlichere Weg. > Ebenso > ist die Einkapselung nicht mehr gegeben, wenn globale Strukturen überall > im Code vorkommen; das gilt doch auch schon für C. Globale Objekte sind bei mir praktisch immer statisch - d.h. nur auf Modul- Ebene sichtbar. Eine Kapselung ist also sehr wohl da. > Und ich persönlich > finde es einfach schöner... Ok, das lasse ich gelten :-) Gruss Uz -- Ullrich von Bassewitz uz@ibb.schwaben.com
Re: Globale Objekte, exception aus Konstruktor
Author: Nico Josuttis
Date: Fri, 11 Aug 1995 07:42
Date: Fri, 11 Aug 1995 07:42
76 lines
4195 bytes
4195 bytes
Vergesst bei der ganzen Diskussion zu globalen Objekten nciht, dass
das Problem unabhaengig davon ist, ob man Exception--Handling hat.
Der Punkt ist, dass bei Verwendung von globalen Objekten
Funktionen VOR main() aufgerufen werden.
Und zwar in einer UNDEFINIERTEN Reihenfolge.
So kann im Anwendungscode keine irgendwie geartete Initialisierung
stattfinden.
Selbst das Ausgeben von Fehlermeldungen mit IOStreams in Konstruktoren
ist dann kritisch, weil nicht sichergestellt ist, dass
die Objekte, wie "cerr" schon initialisiert sind.
Aus diesem Grund:
- VERMEIDE GLOBALE OBJEKTE
Wenn es sich nicht vermeiden laesst:
- KEINE Annahmen ueber igrendwelche Initialisierungen in Konstruktoren
Ist nicht schoen, ich weiss.
So weit mir bekannt ist, gab es auch immer wieder Diskussionen, die
Sprache in dieser Hinsicht (Diskussion einer Initialisierungs--Reihenfolge)
zu erweitern. Den aktuellen Stand weiss ich aber leider nicht.
Eine bessere Loesung wenn von ueberall Zugriff auf ein Objekt gebraucht wird,
ist vielleicht
ist die Verwendung von Hilfsfunktionen, die das Objekt beim ersten
Aufruf mit new erzeugen und dann immer eine Referenz des Objekts
liefern (ist mir gerade so eingefallen, korrigiert mich bitte).
>Globale Objekte bieten sich immer dann an, wenn Du bestimmte Dinge durch-
>fuehren willst, bevor main() startet. Bei einer Klassenblibliothek von mir
>sind das z.B. Registrierungen fuer persistente Objekte. Haette nicht jedes
>Modul ein oder mehrere statische Objekte, die die notwendigen Registrierungen
>durchfuehren, dann muesste der Programmierer das in jedem Programm zu Fuss
>durch Aufrufe von einzelnen Funktionen machen - und das waere bei der
>Vielzahl der persistenten Objekte eine ermuedende und auch sehr fehler-
>anfaellige Geschichte. Das eine Initialisierung nicht durchgefuehrt wurde
>merkst Du naemlich in dem Fall erst recht spaet bzw. u.U. in der Testphase
>ueberhaupt nicht.
Man kann auch bei jedem Zugriff pruefen, ob ein Objekt
existiert bzw. initialisiert ist und es ggf. in dem Moment erzeugen
bzw. initialisieren
(Konstruktor setzt Komponente "istInitialisiert" auf False
und jeder Zugriff prueft das und ruft ggf. eine dann wirklich
initialisierende Funktion auf)
>> Bestimmte Kodierungsstile werden oft deswegen als Bad Design bezeichnet,
>> weil sie letztendlich zu fehleranfälligem Code führen. Globale Objekte
>> werden oft mit einer init()-Memberfunktion initialisiert (anstatt im
>> Konstruktor), weil zB argc,argv erst später zur Verfügung steht.
>
>Ich habe bei mir kein einziges globales Objekt, das mit einer Init() Funktion
>initialisiert wird. Das was Du angibst (Zugriff auf argc und argv) ist einer
>der wenigen denkbaren Faelle, wo das notwendig sein sollte, dann aber liegt
>das Problem woanders, naemlich in der Trennung von Instantiierung und
>Initialisierung, nicht bei den globalen Objekten...
>Und wie oben genannt, waere (zumindest bei meiner Bibliothek) der _Verzicht_
>auf globale Objekte der eindeutig fehleranfaelligere und umstaendlichere
>Weg.
>
Und was machst Du, wenn eine Initialisierung nicht moeglich ist?
(Hoffentlich keine Fehlermeldungen mit IOStreams)
>> Ebenso
>> ist die Einkapselung nicht mehr gegeben, wenn globale Strukturen überall
>> im Code vorkommen; das gilt doch auch schon für C.
>
Hmmm, die Objekte sind global, die Daten darin doch immer noch
gekapselt, oder ?
--------
Nico address: BREDEX GmbH
email: nico@bredex.de Nicolai Josuttis
Fallersleber-Tor-Wall 23
phone: +49 531 24330-0 D-38100 Braunschweig
fax: +49 531 24330-99 Germany
--------
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads