zoukankan      html  css  js  c++  java
  • C++ 的全局构造与析构函数

    我们知道一般的C/C++ 的程序是从main函数开始的,然后在main函数结束后程序结束。但是不然,在main函数开始执行前,已经有其他的指令被执行了。

    为了程序的顺利执行,首先要初始化执行环境,比如堆分配初始化(malloc, free) ,线程子系统等,这里先提一下:C++ 的全局对象构造函数就是在这一时期被执行的。即C++ 的全局对象构造函数在main 函数之前执行,而C++ 全局对象的析构函数在main函数之后被执行。

    linux 系统中,一般程序的入口是“ _start ", 这个函数是Linux系统库(Glibc)的一部分。当我们的程序与Glibc库链接在一起形成最终的可执行文件以后,这个函数就是程序的初始化部分的入口,程序的初始化部分完成一系列初始化过程以后,就会调用main函数来执行程序的主体。在main函数执行完成以后,返回到初始化部分,会进行一系列清理工作,然后结束进程。

    对于有些场合,程序的一些特性的操作必须在main函数之前执行,还有一些操作必须在Mian函数之后执行,这里再提一下C++ .因为最具代表性的就是C++ 的全局对象的构造与析构函数。因此ELF(linux里一种文件格式)文件定义了两种段涉及到了这种信息。

    § .init  该段里边保存的是可执行命令,它构成了进程的初始化代码。因此,当一个程序开始运行时,在main函数被调用前Glibc的初始化部分安排执行这个段中的代码。

    § .fini  该段保存着进程终止代码指令。因此,当一个程序的main函数正常退出时,Glibc会安排执行这个段中的代码。

    因此,这两个段.init 和 .fini的存在有着特别的目的,如果一个函数放到了.init 段,在main函数执行前,系统就会执行它。同理,假如一个函数放到了.fini段,在main函数返回后函数就会被执行。利用这两个特征,C++ 的全局构造函数和析构函数就是这样来的。

    《程序员的自我修养》

  • 相关阅读:
    C# IP地址与数字之间的互转
    C# 获取本机的所有ip地址,并过滤内网ip
    C# POST数据base64到接口会出错的问题
    C# 使用 Task 替换 ThreadPool ,异步监测所有线程(任务)是否全部执行完毕
    C# 线程池执行操作例子
    输入及词法分析详解
    用java实现编译器-算术表达式及其语法解析器的实现
    用java实现一个简易编译器-语法解析
    用java实现一个简易编译器1-词法解析入门
    模板方法模式
  • 原文地址:https://www.cnblogs.com/dormant/p/5065665.html
Copyright © 2011-2022 走看看