C++ 学习笔记 (8) 初识 atexit 函数

atexit 函数

称为终止处理程序注册程序,注册完成以后,当函数终止是exit()函数, 会主动的调用前面注册的各个函数

特点

  1. 调用 exit 函数时,会主动调用被注册的函数,执行清理工作
  2. 发生在 main 函数结束之后
  3. 函数参数是函数的地址
  4. 先注册的函数后实现,类似于栈
  5. 只接受无返回类型,即 void 类型的函数

简单测试:

#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 = "我是默认构造函数" ;
        display ( say ) ;
        atexit ( My_test ) ;
    }
    explicit Gragh ( int _data ) : data ( _data ) {
        const char* say = "我是构造函数" ;
        display ( say ) ;
    }
    // error: cannot convert 'Gragh::My_test' from type 'void (Gragh::)()' to type 'void (*)()' 
    static void My_test () {
        const char* say = "我是类的 static void 函数" ;
        display ( say ) ;
    }
    void test_void () {
        const char* say = "我是 void 的普通成员函数" ;
        display ( say ) ;
    }
    ~Gragh () {
        const char* say = "我是析构函数" ;
        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 ) ;
}

void test4 () {
    const char* say = "I am test4" ;
    display ( say ) ;
    Gragh *One = nullptr ;
    One->test_void () ;
}

bool test5 () {
    const char* say = "I am test5" ;
    display ( say ) ;
    return true ;
}

int main () {
    atexit ( test1 ) ;
    atexit ( test2 ) ;
    atexit ( test3 ) ;
    Gragh *One = new Gragh () ;
    delete One ;
    atexit ( test4 ) ;  // 在 main 函数之后调用
    atexit ( Gragh::My_test ) ;
    // atexit ( test5 ) ;
    // error: invalid conversion from 'bool (*)()' to 'void (*)()' [-fpermissive]
    const char* say = "我是 main 函数" ;
    display ( say ) ;
    return 0 ;
}

程序运行结果:

这里写图片描述

笔记

  1. 被注册的函数类似于入栈,先进后出。这为程序员提供了一种自主决定函数调用先后关系的手段
  2. 被注册的最后一个函数是 static void 函数,所以,最早调用,一般在面对对象中可以采用这种方式释放内存,或者容器清空的操作
  3. 支持普通 void 函数
    支持对象中的 void 函数
    支持类中的 static void 函数。
    原因可能是, atexit 函数是在 main 函数结束之后会被 exit 触发,而 static 关键字是全局的,可见全局变量区和类,对象的的函数的生存期都比 main 的生存期更长
  4. 在 main 函数结束之后,还可以输出语句,说明了 I/O 流的清理工作晚于 main 函数,而且晚于 atexit 函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值