Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Rätselecke » Schlechtes Programm

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 <
010
15.08.2005, 08:28 Uhr
(un)wissender
Niveauwart


Hehe, wohl wahr.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
15.08.2005, 08:40 Uhr
virtual
Sexiest Bit alive
(Operator)



Bearbeitung:
War zu langsam: den einen Fehler habt ihr ja schon!

Okay, also die beiden noch nicht genannten Probleme, welche ich im Auge hatte, sind:

1. Der Destruktor von Manager wirft eine Exception. Das darf aber niemals ein Destruktor tun, denn sonst würde ein solches Programm hier immer aborted :

C++:
   try {
      Manager m1( ... ) ;
      Manager m2( .... );
   }
   catch(...) {
  
   }


Obwohl da ne Exception unterwegs ist, wird der catch-Block nie erreicht: Denn nachdem der dtor von m2 aufgerufen wurde, liegt eine Exception an und das Programm verläßt den try Block in Richtung catch block. Dabei wird aber auch m1 abgeräumt und auch da wird eine Exception geworfen. In dieser Situation wird C++ stets terminate aufrufen. was standardmäßig zum Programmabbruch führt.

2. Der Zuweisungsoperator ist nicht exceptionsicher:

C++:
        Person operator = (Person source) {
                vorname = source.vorname;
                nachname = source.nachname; // ***
                return *this;
        }


Wird in der durch "***" Markierten Zeile eine Exception geworfen (etwa std::bad_alloc), so wird das Objekt, dem zugewiesen wird, in einem inkonsistenten Zustand hinterlassen: dann ist bereits der Vorname übernommen worden, aber der Nachname noch nicht.

Es gibt aber in C++ eine sogenannte Exceptiongarantie, welche die Klassen einhalten sollten: nach dem eine Methode mit einer Exception verlassen wurde, darf kein Objekt in einem inkonsistenten Zustand hinterlassen werden.

Die beiden Punkte bilden zusammen mit dem Problem, daß der dtor von Person nicht virtuell ist die drei IMHO problematischsten Fehler. Alle anderen sind [in diesem Beispiel] Performanceeinbussen (Call by value statt call by reference) bzw. Funktionalitätseinschränkungen (fehlendes const beim copy ctor), welche sich bei einem fertigen Programm höchstens dadurch bemerkbar machen, daß das Programm etwas langsamer läuft als man es sich wünschen könnte.

Die anderen drei verursachen jedoch Programmabstürze, welche ggf. nicht reproduzierbar sind, Speicherlöcher und inkonsistenzen in den Daten.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 15.08.2005 um 08:42 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
15.08.2005, 09:03 Uhr
(un)wissender
Niveauwart


Das mit den Zuweisungsoperator und den Exceptions kannst du auch nur lösen, indem du die beiden std::string-Objekte dynamisch allokierst.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
15.08.2005, 09:23 Uhr
virtual
Sexiest Bit alive
(Operator)


@(un)wissender
Nein. Das kannst Du dadurch lösen, indem Du schreibst:

C++:
        Person& operator = (const Person& source) {
                Person copy(source);
                swap(copy);
                return *this;
         }
         void swap(Person& source) {
                vorname.swap(source.vorname);
                nachname.swap(source.nachname);
        }


Die Stringeigene swap methode ist exceptionsicher, wirft auch keine Exception.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 15.08.2005 um 09:24 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
15.08.2005, 10:06 Uhr
(un)wissender
Niveauwart


Hm, ich wußte nicht, dass string sowas hat. Gut zu wissen. Generell ist es aber wohl nicht immer möglich diese Weg zu beschreiten. Zuweisungoperatoren werfen nunmal manchmal Exceptions, da kann man nichts machen. Wobei, wenn sich alle an das Anbieten einer swap-Methode halten...muss mal drüber nachdenken. Vermutlich geht das tatsächlich meistens.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
15.08.2005, 10:11 Uhr
(un)wissender
Niveauwart


Schaut mal sich das Swap-Konstrukt mal genau an, so wäre es wohl in diesem Fall (generell?) billiger , die beiden Strings wirklich mit new zu erzeugen, vor allem wenn man Person öfter kopiert.
Wenn man dann noch einen guten Allocator hat, sollte das gehen.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
15.08.2005, 10:42 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat von (un)wissender:
Schaut mal sich das Swap-Konstrukt mal genau an, so wäre es wohl in diesem Fall (generell?) billiger , die beiden Strings wirklich mit new zu erzeugen, vor allem wenn man Person öfter kopiert.
Wenn man dann noch einen guten Allocator hat, sollte das gehen.

Das sehe ich anders:
Das, was die spezielisierten swap Methoden machen, ist ja was anderes als das swap Funktions-template: Letzteres ist zwar hochgradig flexibel aber eben auch hochgradig inperformant:
1. Aufruf eines Copy-Constructors
2. Aufruf des Zuweiungsoperators, welcher im Sinne der Exceptionsicherheit wiederum eine Copy-Constructor impliziert (jedenfalls häufig) und
3. Destruktor aufrufe der beiden zuvor erzeugten Objekte.
Da wird also genewt ohne ende.

Die spezialisierten String - swap routinen hängen natürlich maßgeblich von der Stringimplementierung ab. Man kann aber meist davon ausgehen, daß ein String eben intern lediglich einen Pointer swappen muß, was extrem billig ist (Bei der GNU STL ist das zB so). Kann natürlich auch teuerer sein, aber niemals teuerer als ein new, weil die Klasse am besten selbst weiß, wie man effizient swappen kann.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
15.08.2005, 11:42 Uhr
(un)wissender
Niveauwart


Hm, es kommt wirklich drauf an was man will. Es kann durchaus billiger sein, die beiden String mit new zu erzeugen, wenn man bspw. Referenzzählung hinzunimmt. Das wiederum nervt natürlich bei Multithreading...
Ich werde mir die swap-Theorie näher anschauen, scheint nicht verkehrt zu sein.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 <     [ Rätselecke ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: