這個問題出現在,程序里有一個數據庫對象,是被全局依賴的,剛開始的時候程序比較簡單。后來程序變復雜了,有多個全局對象依賴它。那么問題來了,我能不能讓它們自動按順序初始化?
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.總結:最好不要用全局對象,即使用了全局對象,初始化的時候也最好放在一個文件里。如果一定要用全局對象,需要注意全局對象的初始化順序依賴問題。