C++中如何指定全局对象的初始化顺序

这个问题出现在,程序里有一个数据库对象,是被全局依赖的,刚开始的时候程序比较简单。后来程序变复杂了,有多个全局对象依赖它。那么问题来了,我能不能让它们自动按顺序初始化?

1.首先从简单的情况看看,最简单的了,就是这样子,还是用代码来演示吧:

#include<cstdio>
using namespace std;
class A
{
public:
      A(int id):id(id) { 
            printf("A::A(),id=%d\n", id);
       }
      ~A() { 
             printf("A::~A(),id=%d\n", id); 
        }
private: 
         int id;
};


A a1(1);
A a2(2);
int main()
{
     A a(3);  
     return 0;
}

执行后得到:

A::A(),id=1
A::A(),id=2
A::A(),id=3
A::~A(),id=3
A::~A(),id=2
A::~A(),id=1

从gcc的表现来看,在单个文件里,全局对象的初始化是按出现的顺序来的。

2.在上面的基础上,将全局对象分布到不同的文件里看看会怎么样

cpp1

#include "ck.h"
using namespace std;

A a1(1);
A a4(4);
int main()
{
   A a(3);
   return 0;
}

cpp2

#include "ck.h"
A a2(2);
A a5(5);

ck.h

#include<cstdio>
using namespace std;
class A
{
public:
  A(int id):id(id) { 
        printf("A::A(),id=%d\n", id); 
    }
  ~A() { 
        printf("A::~A(),id=%d\n",id);
     }
private:  
        int id;
};

编译执行得到的结果是:

A::A(),id=2
A::A(),id=5
A::A(),id=1
A::A(),id=4
A::A(),id=3
A::~A(),id=3
A::~A(),id=4
A::~A(),id=1
A::~A(),id=5
A::~A(),id=2

看不出有什么顺序?或者本来就是乱序?但还是能够看出来,同一个文件里的全局对象是按顺序的,不同文件的就很难说了。

3.能不能不要猜?或者说强制指定编译顺序?

gcc提供了一个特性,利用它可以指定对象的初始化优先级,例如

Some_Class  A  __attribute__ ((init_priority (2000)));
Some_Class  B  __attribute__ ((init_priority (543)));

利用它我们可以达到自己想要的目的,将上面的代码修改为:

A a1  __attribute__ ((init_priority (1000))) (1);
A a4  __attribute__ ((init_priority (4000))) (4);

A a2 __attribute__ ((init_priority (2000))) (2);
A a5 __attribute__ ((init_priority (5000))) (5);

执行得到的结果为:

A::A(),id=1
A::A(),id=2
A::A(),id=4
A::A(),id=5
A::A(),id=3
A::~A(),id=3
A::~A(),id=5
A::~A(),id=4
A::~A(),id=2
A::~A(),id=1

经过验证,使用init_priority确实能够达到我想要的效果。

4.代码级解决方案

如果觉得编译器的方案也不是很完善,不能自己把握全局,那就自己写一个管理器,在管理器里对各个对象进行顺序初始化。这里的代码我就不演示了。

5.总结:最好不要用全局对象,即使用了全局对象,初始化的时候也最好放在一个文件里。如果一定要用全局对象,需要注意全局对象的初始化顺序依赖问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容