#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)吧

原文链接: https://www.cnblogs.com/hgy413/archive/2011/10/15/3693581.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    #pragma init_seg 对象的初始化和析构顺序

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/34421

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午11:21
下一篇 2023年2月8日 上午11:21

相关推荐