c + + - Afslut applikationen OG kalder destruktorer af lokale objekter

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har nogle objekter på stakken i hovedfunktionen:


int main(...)
{
   CFoo foo;
   CBar bar;
}


Jeg har også en funktion, der holder styr på fejl i min ansøgning:


void Err(std::string msg)
{
   SomehowLogErrorMessage(msg);
   exit(1);
}


Err funktion er helt sikkert nyttigt, når jeg skal rapportere en fatalt fejl. Jeg logger bare fejlen og afslutter applikationen - den kan ikke gendannes efter sådanne fejl. Men at afslutte med 'exit ()' påberåber ikke foo og bar destructors - en adfærd, som jeg faktisk forventede (men var forkert). 'abort ()' hjælper heller ikke. Også Jeg kan ikke bruge undtagelser for at fange dem i main (). Er der nogen anden måde at implementere Err-funktion på, så den afslutter appen og korrekt renser stakken genstande? Eller skal jeg på en eller anden måde redesigne min fejlhåndtering?


Tak!





P.S. Forhåbentlig kan jeg ikke sende WM\_QUIT-besked til mit hovedvindue? Jeg er ikke god med WinAPI, men min app er ren Win32 og min Err () -funktion kan få et håndtag til mit hovedvindue. Vil det virke?

Bedste reference


Ikke uden undtagelser eller retur normalt fra Err hele vejen op på callstacken. Du skal slappe af stablen.

Andre referencer 1


Der er stadig C 's setjmp og longjmp. Det burde bringe dig tilbage til main, så programmet afsluttes som sædvanligt efter at have overskredet main, i hvilket tilfælde C ++ 's destructormekanisme vil ødelægge dine lokale objekter i main.


Selvfølgelig er der brug af longjmp frynsede i C ++ af gode grunde. Det vil springe over alle andre funktioner på stakken, så det virker kun for nogle få stakobjekter i main.


Det kan være nemmere at allokere dine objekter på bunken og delete dem manuelt i Err.

Andre referencer 2


Der er stort set to metoder til udbredelse af fejl i C ++: Undtagelser (som du tilsyneladende har udelukket vilkårligt) og returkoder.


Da du ikke kan bruge undtagelser, skal du begynde at sende returkoder fra dine funktioner, der kan mislykkes, og teste dem for at se, om du skal stoppe og vende tilbage til hovedmenuen. Hvis du ikke undviker stakken som denne, er der ingen måde at sikre, at destruktorer bliver kaldt korrekt.


Overvej også, at hvis dit program er i en dødelig tilstand, vil destruktorer rent faktisk kunne rydde op forventet? Hvad hvis objekttilstanden er mangelfuld og ikke kan hentes ordentligt? I stedet for at ringe exit kan du ringe abort, som i det mindste ville forlade en kerne for at hjælpe med at diagnosticere problemet, hvis du kommer i dårlig tilstand. fejl, hvor undtagelser er utilgængelige, dette er et rimeligt valg.

Andre referencer 3


Jeg tror Exit vil opsige ansøgningen straks. For at se den adfærd, du forventer foo og bar, skal gå ud af omfanget. Det betyder, at hovedfunktionen skulle slutte normalt med en returværdi. I stedet for at kalde Exit() ud af din Err-funktion, skal du finde en måde at vende tilbage til din hovedfunktion og lade den normalt returnere med en fejlværdi.

Andre referencer 4


Jeg ville omstrukturere din fejlhåndtering. Den mest enkle ting at gøre er at vende tilbage til main, og lad det gøre sin normale oprydning. Undtagelser giver denne mulighed ved hjælp af stabling, men du kan ikke bruge undtagelser. OK, det er fint. Nogle gange kan du ikke bruge undtagelser.


Så i stedet for at Err forsøge at lukke programmet ned, skal Err logge fejlen og returnere en fejlkode. Ideelt set bør Err ikke gøre to job alligevel, som du forsøger at få det til at gøre: 1) Log fejlen, 2) Afslut appen yndefuldt.


Hvis din ansøgning tilfældigvis er multithreaded, har du måske en fejlfri udgave. I fejllogningstråden skal du signalere en 'dø' -hændelse. Har hovedtråden vente på denne begivenhed sammen med hvad som helst det venter på (eller indsprøjt et job til det via QueueUserAPC eller lignende). Når begivenheden signaleres, skal du lukke appen ned.