atexit function
Called termination handler registrar, after registration is complete, when the function terminates as exit() function, it actively calls the previously registered functions
Characteristic
- When the exit function is called, the registered function is actively called to perform cleanup
- Occurs after the end of the main function
- A function parameter is the address of the function
- Registered functions followed by implementation, similar to stacks
Simple test:
#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define display( say ) std::cout << std::endl << say << std::endl
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;
using std::cin ;
using std::cout ;
using std::endl ;
using std::string ;
class Gragh {
private:
int data ;
public:
Gragh () : data ( 0 ) {
const char* say = "I am the default constructor" ;
display ( say ) ;
atexit ( My_test ) ;
}
explicit Gragh ( int _data ) : data ( _data ) {
const char* say = "I am a constructor" ;
display ( say ) ;
}
// error: cannot convert 'Gragh::My_test' from type 'void (Gragh::)()' to type 'void (*)()'
static void My_test () {
const char* say = "I am static void function" ;
display ( say ) ;
}
~Gragh () {
const char* say = "I am a destructor" ;
display ( say ) ;
}
} ;
void test1 () {
const char* say = "I am test1" ;
display ( say ) ;
}
void test2 () {
const char* say = "I am test2" ;
display ( say ) ;
}
void test3 () {
const char* say = "I am test3" ;
display ( say ) ;
}
int main () {
atexit ( test1 ) ;
atexit ( test2 ) ;
atexit ( test3 ) ;
Gragh *One = new Gragh () ;
delete One ;
const char* say = "I am main function" ;
display ( say ) ;
return 0 ;
}
Program run results:
note
- Registered functions are like stacking, FIFO.This provides a way for programmers to determine the order of function calls
- The last function to be registered is the static void function, so the earliest call, generally in the face of an object, can release memory in this way, or container emptying operations
- Normal member functions are not supported and errors will occur:
error: cannot convert 'Gragh::My_test' from type 'void (Gragh::)()' to type 'void (*)()' .
However, the static function in the object is supported.
This may be because the atexit function is triggered by exit after the main function ends, and the static keyword is global, so the global variable area has a longer lifetime than the code area. - After the main function finishes, you can also output statements indicating that the cleanup of I/O streams is later than the main function and later than the atexit function.