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.總結:最好不要用全局對象,即使用了全局對象,初始化的時候也最好放在一個文件里。如果一定要用全局對象,需要注意全局對象的初始化順序依賴問題。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容