Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Exceptions

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 ] [ 3 ]
000
04.02.2004, 15:44 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


so könnt ihr mir bitte mal erklären wie ich mit exceptions arbeiten muss?
habe das noch nie gemacht und immer returnvalues verwendet...

angenommen ich habe mir eine Klasse Bildaufnahme gebastelt...

C++:
//Konstruktor
Bildaufnahme::Bildaufnahme(char* dcf_filename, char* system, int CamOrFile){

    this->CamOrFile=CamOrFile;

    if(M_NULL==MappAlloc (M_DEFAULT, &MilApplication)) throw ApplicationAllocError;
    if(M_NULL==MsysAlloc (L"system", M_DEFAULT, M_DEFAULT, &MilSystem))throw SystemAllocError;
    if(M_NULL==MdigAlloc (MilSystem, M_DEFAULT, dcf_filename, M_DEFAULT, &MilDigitizer) throw DigitizerAllocError;

...
...
}



so und nun zu meinem problem.. wie definiere ich erstens meine fehler also ApplicationAllocError,SystemAllocError,DigitizerAllocError

und wie benutze ich das nachher

geht das dann so?

C++:
Bildaufnahme *ba; //muss mit pointer sein... will ich hier jetzt nicht ausführlich erläutern warum...
....

try{
ba=new Bildaufname(.....);

}
catch(ApplicationAllocError ae){...}
catch(SystemAllocError ae){...}
catch(DigitizerAllocError de){...}
//und wie bekomme ich hier am ende noch ein default also sonstiger fehler ran?


--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
04.02.2004, 15:49 Uhr
0xdeadbeef
Gott
(Operator)


Du musst den Konstruktor an der Stelle explizit aufrufen, also:

C++:
throw ApplicationAllocError();


aber ansonsten ja.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
04.02.2004, 15:52 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


wie Konstruktor?
welchen Konstruktor...Muss ApplicationAllocError ne eigene Klasse sein?
wenn ja wie definier ich das am besten...Ich will ja nicht für jede der drei exceptions ein eigene Klasse definieren sondern nur drei spezielle ausprägungen haben...wie muss ich das machen...Bitte bitte ein beispiel...Ich peil das gerade nicht...

ach so und noch was was ist mit dem object das ich für den zeiger ba allokiert hätte? würde das im fall eienr exception existieren oder nicht... das muss ich ja wissen um den speicher gegebenenfalls freigeben zu können...
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 04.02.2004 um 15:52 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
04.02.2004, 16:09 Uhr
0xdeadbeef
Gott
(Operator)


Du kannst auch nen int durch die Gegend schmeißen, wenn du unbedingt willst. Aber einen Datentyp brauchst du. Wenn aus einem Konstruktor ne Exception geschmissen wird...au weia... virtual?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
04.02.2004, 16:39 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

einem Konstruktor ne Exception geschmissen wird...au weia... virtual?


jo genau das habe ich mich auch gefragt... und wenn man das so nicht macht wie macht man es dann? eine blöde variable vorhalten in der man nach aufruf des konstruktors nachschauen kann obs geklappt hat...
das ist ja dann auch scheisse dann kann ich mir den exceptionkrempel ja gleich sparen...
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 04.02.2004 um 16:39 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
04.02.2004, 16:55 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat:
0xdeadbeef postete
Exception geschmissen wird...au weia... virtual?

Ja?
Ich sehe kein Problem: Wird im ctor ne Exception geworfen, wird alle bisher konstruierte wieder freiegegeben, dh insbes. alle Basisklasse werden wieder abgeräumt. Natürlich muß man ein wenig aufpassen:

C++:
class NaiveClass: public BasicClass
{
   NaiveClass() :BasicClass
   {
       char* x = new char[100];
       char* y = new char[1000000000];
       ...
       delete[]y;
       delete[]x;
   }
};


Es gibt eine gute Wahrscheinlichkeit, daß das new für y schief geht. Ohne vorkehrungen hat man ein Speicherloch, weil x nicht freigeben wird. Dies ist allerdings eine Angelegenheit, die unabh. von ctor zu beachten ist (dh das gleiche kann auch in eienr normalen methode passieren).

Problematisch sind lediglich Exceptions, die aus Destructoren heraus geworfen werden: diese sollten (um jeden Preis) verhindert werden:

C++:
class BadClass
{
public:
     virtual ~BadClass()
     {
          throw "I'm just bad";
     }
};

...
void f()
{
     try
     {
        BadClass bad1;
        ...
        throw "I am a normal String thrown f";
     } // Problematische Stelle!
     catch(...)
     {
     }
}


Die Problematische Stelle ist mit einem Kommentar versehen: In der Zeile darüber wird eine Exception geworfen, dh der try Block wird verlassen und alle lokalen Variablen dieses Blocks werden freigeben. Dies bedeutet, daß der dtor von BadClass implizit aufgerufen wird, so daß man plötzlich - während die erste Exception noch nicht gefangen ist - eine zweite am Hals hat. Dies wird von C++ mit einem Aufruf von std::unexpected() quitiert, was wiederum (solange man nichts anderes sagt zu einem std::terminate() führt (der Name ist programm: Das Programm terminiert!)).
Ganz davon abgesehen bewirkt eine Exception im dtor, daß ein Object ggf. nicht komplett abgeräumt wird und so ein Speicherloch produiert. Fürde etwas im Bsp ganz oben der dtor von NaiveClass eine Exception werfen, würde nicht mehr der dtor von BasicClass erreicht.

Mit std::uncaught_exception() kann übrigens herausfinden, ob man grade in der Situation ist, daß die lokalen Variablen abgeräumt werden, um im catch Block zu landen:

C++:
class BadClass
{
public:
     virtual ~BadClass()
     {
          if(std::uncaught_exception()) std::cerr <<" Gleich gehts in the catch block, weil was dummes passiert ist!"<<std::endl;
     }
};

...
void f()
{
     try
     {
        BadClass bad1;
        ...
        throw "I am a normal String thrown f";
     } // Gibt obigen text aus!
     catch(...)
     {
     }
  
     try
     {
        BadClass bad1;
        ...
     } // Gibt obigen text nicht aus, wiel keine exception geworfen wurde!
     catch(...)
     {
     }
}



Bearbeitung:
Sorry für die Rechtschreibfehler. Ich bin aber zu müde, sie alle rauszuholen

--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 04.02.2004 um 16:57 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
04.02.2004, 17:07 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


beantwortet glaube ich nicht ganze meine frage...oder doch?

was ist denn nun mit

C++:

Bildaufnahme *ba = new Bildaufnahme(.....);


was ist wenn hier die exception geschmissen wird? zeigt ba dann auf null? oder nicht? und wie meinst du das mit dem das man das problem sowieso hat... soll man dann in dem catch-block von hand abräumen? das wäre ja super Sch**sse.. dann kann ich mir ja auch gleich die Klasse sparen wenn ichs sowieso nicht kaspeln kann oder wie siehst du das?
vor allen dingen wie kann ich den speicher wieder freigeben wenn das object und damit der pointer auf den der speicher gezeigt hat gar nicht mehr existiert?
muss ich das dann vielleicht kurz vor dem throw machen?

was zum henker ist ctor? (soll das Konstruktor heissen oder ist damit wieder oder was gemeint was ich nicht kenne?)
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 04.02.2004 um 17:09 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.02.2004, 18:36 Uhr
virtual
Sexiest Bit alive
(Operator)


Mit ctor ist Constructor gemeint, mit dtor Destructor.

Also in Deinem Beispiel müsst Du die Fehler fangen, zB so:

C++:
Bildaufnahme::Bildaufnahme(char* dcf_filename, char* system, int CamOrFile){

    this->CamOrFile=CamOrFile;
    MilApplication = NULL;
    MilSystem = NULL;
    MilDigitizer = NULL;
    try
    {
        if(M_NULL==MappAlloc (M_DEFAULT, &MilApplication)) throw ApplicationAllocError;
        if(M_NULL==MsysAlloc (L"system", M_DEFAULT, M_DEFAULT, &MilSystem))throw SystemAllocError;
        if(M_NULL==MdigAlloc (MilSystem, M_DEFAULT, dcf_filename, M_DEFAULT, &MilDigitizer) throw DigitizerAllocError;
        [...]
     }
     catch (...)
     {
        if (MilDigitizer) MdigFree(MilDigitizer);
        if (MilSystem) MsysFree(MilSystem);
        if (MilApplication) MappFree(MilApplication);
        
        [...]
     }
}



Bei

C++:
Bildaufnahme *ba = new Bildaufnahme(.....);


sit im Falle einer Exception ba inhaltlich nicht definiert, daher vielleicht:

C++:
Bildaufnahme *ba = NULL;
ba = new Bildaufnahme(.....);


--
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
008
04.02.2004, 18:57 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@virtual
sorry das versteh ich gar nicht...
meine idee war es eigentlich die exception ausserhalb der klasse aufzufangen und nicht innerhalb...
wenn ich das innerhalb des konsturktors machen will brauch ich keine exceptions oder? das kann man doch auch locker ohne machen... das macht macht imho den code nur unübersichtlich...

und noch ne frage so wie du es geschrieben hast... wird der destruktor nun noch aufgerufen wenn eine exception ausgelöst wurde oder nicht, weil jetzt springt er ja nur zum ende des konstruktors?...das object müsste es dann ja noch geben...


was genau meinst du mit inhaltlich nicht definiert? new muss doch was zurückliefern oder? und wenns mit der allokiererei nicht klappt.. bzw wenn ich mitten im konsturktor abbreche dann gibt es doch kein objekt oder? folglich hat new fehlgeschlagen und muss null zurückliefern...


was ist nun wenn ich versuchen würde die exception ausserhalb der klasse zu fetchen (also beim aufruf mit new)? wie läuft das dann ab?
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 04.02.2004 um 18:58 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
04.02.2004, 20:06 Uhr
(un)wissender
Niveauwart



C++:
#include <new>
.
.
.
Bildaufnahme *ba = NULL;
try {
     ba = new Bildaufnahme();
}catch(std::bad_alloc &ba)



Wenn der Konstruktor nicht vollständig ausgeführt wurde, dann wird der Destruktor auch nicht aufgerufen.
Exceptions immer per Referenz fangen.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ]     [ C / C++ (ANSI-Standard) ]  


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: