zoukankan      html  css  js  c++  java
  • #pragma init_seg 对象的初始化和析构顺序



    先进后出原则,最先初始化的最后析构!

    1.C++中全局对象、变量的构造函数调用顺序是跟声明有一定关系的,即在同一个文件中先声明的先调用。对于不同文件中的全局对象、变量,它们的构造函数调用顺序是未定义的,取决于具体的编译器

    2.C++总是按成员变量在类声明中出现的顺序来初始化成员变量的,为什么C++不按初始化列表的顺序来初始化成员变量呢?因为我们知道初始化的顺序应该与析构的顺序相反,而对一个类来说 constructor 可能有多个,初始化列表也会有多个,所以C++就选择了简单的点的方法,按成员变量出现的顺序来初始化。

    3.基类的静态变量先初始化,然后是它的派生类。直到所有的静态变量都被初始化。这里需要注意全局变量和静态变量的初始化是不分次序的。这也不难理解,其实静态变量和全局变量都被放在公共内存区。可以把静态变量理解为带有“作用域”的全局变量

           顺序为:  1基类的静态变量或全局变量 2派生类的静态变量或全局变量 3基类的成员变量 4派生类的成员变量

    #pragama init_seg 预处理器指令

    C++标准中,处于同一编译单元(cpp)的全局对象按其声明次序初始化并倒序析构,但标准中没有说处于不同编译单元的全局对象的初始化顺序。这带来了很多问题。

    假如有个Log对象负责程序日志的记录。如果程序结束时,有某个全局对象出现类似于资源释放失败的错误,该对象会调用Log记录错误,这时,Log可能已经被销毁了…… 这就是所谓的dead-reference问题。

    pragma init_seg(compiler)
    #pragma init_seg(lib)
    #pragma init_seg(user)
    #pragma init_seg("user_defined_segment_name")

    init_seg 预处理器指令: 编译器、 库、 用户,和"user_defined_segment_name

    前三个指令,初始化优先次序依次降低,但都先于普通的全局变量构造,如cout就是使用compiler级别构造的

    注:一个源文件只能出现一次init_seg 指令

    pragma init_seg(compiler)是保留给微软 C/C++ 运行库使用的,我们不应该使用它!
    在我们自己的代码里,如果希望一些对象先于其他对象初始化,我们可以使用 #pragma init_seg(lib) 指令

    // file2.cpp
    // command line: cl /c file2.cpp
    #pragma init_seg(lib)
    #include<iostream.h>
    class MyLibClass
    

     还是不要在库中用#pragma init_seg(lib), 不然 warning C4073: 初始值设定项放置在库初始化区域中,然后挂掉了!!

    还是用#pragma init_seg(user)吧

  • 相关阅读:
    【20171123】【GITC精华演讲】贝业新兄弟李济宏:如何做到企业信息化建设的加减乘除
    920记者招待会: 对话详解海尔张瑞敏首席的人单合一
    存货控制中的ABC分类释义
    对员工宽容的公司 都死掉了
    小型互联网公司的IT系统建设思路
    第三方物流是什么
    伟哥对RTO & RPO的通俗理解
    【20170506】贝业新兄弟IT总监李济宏:第三方家居物流的IT架构探索
    【Vegas原创】VirtualBox扩容、分割的整体方案
    数据通信基础(物理层)学习笔记
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693581.html
Copyright © 2011-2022 走看看