🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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
#202
Author: Stephen Friedrich
Date: Wed, 02 Aug 1995 13:45
104 lines
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
#217
Author: Ralf W. Stephan
Date: Fri, 04 Aug 1995 10:06
12 lines
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
#218
Author: Ullrich von Bassewitz
Date: Fri, 04 Aug 1995 20:33
31 lines
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
#219
Author: Ralf W. Stephan
Date: Sat, 05 Aug 1995 13:14
39 lines
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
#222
Author: Ullrich von Bassewitz
Date: Sun, 06 Aug 1995 14:09
65 lines
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
#247
Author: Nico Josuttis
Date: Fri, 11 Aug 1995 07:42
76 lines
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