這個(gè)問(wèn)題出現(xiàn)在,程序里有一個(gè)數(shù)據(jù)庫(kù)對(duì)象阳堕,是被全局依賴(lài)的跋理,剛開(kāi)始的時(shí)候程序比較簡(jiǎn)單。后來(lái)程序變復(fù)雜了恬总,有多個(gè)全局對(duì)象依賴(lài)它前普。那么問(wèn)題來(lái)了,我能不能讓它們自動(dòng)按順序初始化壹堰?
1.首先從簡(jiǎn)單的情況看看拭卿,最簡(jiǎn)單的了,就是這樣子贱纠,還是用代碼來(lái)演示吧:
#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;
}
執(zhí)行后得到:
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的表現(xiàn)來(lái)看峻厚,在單個(gè)文件里,全局對(duì)象的初始化是按出現(xiàn)的順序來(lái)的谆焊。
2.在上面的基礎(chǔ)上惠桃,將全局對(duì)象分布到不同的文件里看看會(huì)怎么樣
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;
};
編譯執(zhí)行得到的結(jié)果是:
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
看不出有什么順序?或者本來(lái)就是亂序辖试?但還是能夠看出來(lái)辜王,同一個(gè)文件里的全局對(duì)象是按順序的,不同文件的就很難說(shuō)了罐孝。
3.能不能不要猜呐馆?或者說(shuō)強(qiáng)制指定編譯順序?
gcc提供了一個(gè)特性肾档,利用它可以指定對(duì)象的初始化優(yōu)先級(jí)摹恰,例如
Some_Class A __attribute__ ((init_priority (2000)));
Some_Class B __attribute__ ((init_priority (543)));
利用它我們可以達(dá)到自己想要的目的辫继,將上面的代碼修改為:
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);
執(zhí)行得到的結(jié)果為:
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
經(jīng)過(guò)驗(yàn)證怒见,使用init_priority確實(shí)能夠達(dá)到我想要的效果。
4.代碼級(jí)解決方案
如果覺(jué)得編譯器的方案也不是很完善姑宽,不能自己把握全局遣耍,那就自己寫(xiě)一個(gè)管理器,在管理器里對(duì)各個(gè)對(duì)象進(jìn)行順序初始化炮车。這里的代碼我就不演示了舵变。
5.總結(jié):最好不要用全局對(duì)象酣溃,即使用了全局對(duì)象,初始化的時(shí)候也最好放在一個(gè)文件里纪隙。如果一定要用全局對(duì)象赊豌,需要注意全局對(duì)象的初始化順序依賴(lài)問(wèn)題。