Freigeben über


Beendigung des C++-Programms

In C++ können Sie ein Programm auf folgende Weise beenden:

  • Rufen Sie die Funktion exit auf.
  • Rufen Sie die Funktion abort auf.
  • Führen Sie eine return Anweisung aus main.

exit-Funktion

Die exit in <stdlib.h> deklarierte Funktion beendet ein C++-Programm. Der als Argument exit angegebene Wert wird als Rückgabecode oder Beendigungscode des Programms an das Betriebssystem zurückgegeben. Gemäß der Konvention bedeutet ein Rückgabecode von Null, dass das Programm erfolgreich abgeschlossen wurde. Sie können die Konstanten EXIT_FAILURE und EXIT_SUCCESS, auch in <stdlib.h> definiert, verwenden, um Erfolg oder Fehler Ihres Programms anzugeben.

abort-Funktion

Die abort funktion, die auch im Standard deklariert ist, enthält datei <stdlib.h>, beendet ein C++-Programm. Der Unterschied besteht darin exit abort , dass exit die C++-Laufzeitendierungsverarbeitung stattfindet (globale Objektdestruktoren werden aufgerufen). abort beendet das Programm sofort. Die abort Funktion umgeht den normalen Vernichtungsprozess für initialisierte globale statische Objekte. Außerdem wird jegliche spezielle Verarbeitung umgangen, die mit der atexit-Funktion angegeben wurde.

Microsoft-spezifisch: Aus Gründen der Windows-Kompatibilität kann die Microsoft-Implementierung abort von DLL-Beendigungscode unter bestimmten Umständen die Ausführung von DLL-Beendigungscode ermöglichen. Weitere Informationen finden Sie unter abort.

atexit-Funktion

Verwenden Sie die atexit Funktion, um Aktionen anzugeben, die ausgeführt werden, bevor das Programm beendet wird. Vor der Ausführung der Exit-Processing-Funktion werden keine globalen statischen Objekte initialisiert, bevor der Aufruf atexit zerstört wird.

return Anweisung in main

Mit der return Anweisung können Sie einen Rückgabewert von main. Eine return Anweisung in main erster Linie verhält sich wie jede andere return Anweisung. Alle automatischen Variablen werden zerstört. Ruft dann main mit dem Rückgabewert als Parameter auf exit . Betrachten Sie das folgende Beispiel:

// return_statement.cpp
#include <stdlib.h>
struct S 
{
    int value;
};
int main()
{
    S s{ 3 };

    exit( 3 );
    // or
    return 3;
}

Die exit Anweisungen und return Anweisungen im vorherigen Beispiel weisen ein ähnliches Verhalten auf. Beenden Sie das Programm, und geben Sie einen Wert von 3 an das Betriebssystem zurück. Der Unterschied besteht darin, dass exit die automatische Variable snicht zerstört wird, während die return Anweisung ausgeführt wird.

Normalerweise erfordert C++ funktionen, die andere Rückgabetypen als void den Rückgabewert aufweisen. Die Funktion ist eine Ausnahme. Sie main kann ohne Anweisung return enden. In diesem Fall wird ein implementierungsspezifischer Wert für den aufrufenden Prozess zurückgegeben. (Standardmäßig gibt MSVC 0 zurück.)

Zerstörung von Thread- und statischen Objekten

Wenn Sie direkt (oder wenn sie nach einer Anweisung von maineiner return Anweisung aufgerufen wird) aufrufenexit, werden threadobjekte, die dem aktuellen Thread zugeordnet sind, zerstört. Als Nächstes werden statische Objekte in umgekehrter Reihenfolge ihrer Initialisierung zerstört (nach aufrufen von Funktionen atexit, die angegeben sind , falls vorhanden). Das folgende Beispiel zeigt, wie so eine Initialisierung und Bereinigung funktionieren.

Beispiel

Im folgenden Beispiel werden die statischen Objekte sd1 erstellt und sd2 vor dem Eintrag maininitialisiert. Nachdem dieses Programm die Verwendung der return Anweisung beendet hat, wird zuerst sd2 zerstört und dann sd1. Der Destruktor für die Klasse ShowData schließt die Dateien, die diesen statischen Objekten zugeordnet sind.

// using_exit_or_return1.cpp
#include <stdio.h>
class ShowData {
public:
   // Constructor opens a file.
   ShowData( const char *szDev ) {
   errno_t err;
      err = fopen_s(&OutputDev, szDev, "w" );
   }

   // Destructor closes the file.
   ~ShowData() { fclose( OutputDev ); }

   // Disp function shows a string on the output device.
   void Disp( char *szData ) {
      fputs( szData, OutputDev );
   }
private:
   FILE *OutputDev;
};

//  Define a static object of type ShowData. The output device
//   selected is "CON" -- the standard output device.
ShowData sd1 = "CON";

//  Define another static object of type ShowData. The output
//   is directed to a file called "HELLO.DAT"
ShowData sd2 = "hello.dat";

int main() {
   sd1.Disp( "hello to default device\n" );
   sd2.Disp( "hello to file hello.dat\n" );
}

Eine weitere Möglichkeit zum Schreiben dieses Codes besteht darin, die ShowData Objekte mit Blockbereich zu deklarieren, wodurch sie implizit zerstört werden, wenn sie außerhalb des Gültigkeitsbereichs gehen:

int main() {
   ShowData sd1( "CON" ), sd2( "hello.dat" );

   sd1.Disp( "hello to default device\n" );
   sd2.Disp( "hello to file hello.dat\n" );
}

Siehe auch

main Funktions- und Befehlszeilenargumente