C++ プログラムの終了
C++ では、次の方法でプログラムを終了できます:
exit 関数
<stdlib.h> で宣言された exit 関数は、C++ プログラムを終了します。 exit の引数として指定された値は、プログラムのリターン コードまたは終了コードとしてオペレーティング システムに返されます。 慣例により、ゼロのリターン コードは、プログラムが正常に完了したことを意味します。 <stdlib.h> で定義された定数 EXIT_FAILURE と EXIT_SUCCESS を使用して、プログラムの成功または失敗を示すことができます。
main 関数から return ステートメントを発行することは、戻り値を引数として exit 関数を呼び出すことと同じです。
abort 関数
標準インクルード ファイルの <stdlib.h> で宣言された abort 関数も、C++ プログラムを終了します。 exit と abort の違いは、exit では C++ ランタイムの終了プロセスが実行されますが (グローバル オブジェクトのデストラクターが呼び出されます)、abort ではプログラムが直ちに終了される点です。 abort 関数では、初期化されたグローバルな静的オブジェクトの通常のデストラクション処理は実行されません。 また、atexit 関数を使用して指定されている特殊な処理も実行されません。
atexit 関数
プログラムが終了する前に実行されるアクションを指定するには、atexit 関数を使用します。 atexit の呼び出し以前に初期化されたグローバル静的オブジェクトは、終了処理関数の実行前に破棄されません。
main の return ステートメント
main から return ステートメントを発行することは、exit 関数を呼び出すことと機能的には同じです。 次の例を確認してください。
// return_statement.cpp
#include <stdlib.h>
int main()
{
exit( 3 );
return 3;
}
前の例の exit ステートメントと return ステートメントは、機能的に同じです。 ただし、C++ では、void 以外の戻り値の型を持つ関数は、値を返す必要があります。 main 関数は例外であり、return ステートメントなしで終了できます。 その場合は、呼び出しプロセスに実装固有の値を返します。 return ステートメントを使用すると、main から戻り値を指定できます。
静的オブジェクトの破棄
exit を呼び出すか main から return ステートメントを実行すると、静的オブジェクトが初期化と逆の順序で破棄されます (存在する場合は atexit の呼び出しの後)。 次の例は、こうした初期化やクリーンアップがどのように機能するのかを示します。
例
以下の例では、静的オブジェクト sd1 と sd2 は、main に入る前に作成、初期化されます。 このプログラムが return ステートメントを使用して終了した後、最初に sd2 が破棄され、その後に sd1 が破棄されます。 ShowData クラスのデストラクターは、これらの静的オブジェクトに関連付けられたファイルを閉じます
// 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" );
}
このコードを作成するもう 1 つの方法は、ブロック スコープを持つ ShowData オブジェクトを宣言して、スコープ外に出ると破棄できるようにすることです。
int main() {
ShowData sd1( "CON" ), sd2( "hello.dat" );
sd1.Disp( "hello to default device\n" );
sd2.Disp( "hello to file hello.dat\n" );
}