这个问题出现在,程序里有一个数据库对象,是被全局依赖的,刚开始的时候程序比较简单。后来程序变复杂了,有多个全局对象依赖它。那么问题来了,我能不能让它们自动按顺序初始化?
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.总结:最好不要用全局对象,即使用了全局对象,初始化的时候也最好放在一个文件里。如果一定要用全局对象,需要注意全局对象的初始化顺序依赖问题。
网友评论