Longevity控制析構順序。默認情況下,全局變量和static全局變量的析構順序是根據初始化順序反着析構。
OrderedStatic代碼幾個比較有意思值得學習的地方貼出來一下,其它有些與單件模式的一樣不再重述。
1、退出函數atexit
通過設置該接口,控制exit後,C++調用的用戶自己設置的全局退出函數
std::atexit(Private::AtExitFn);該接口支持多次調用,設置多個退出函數
2、成員函數,函數指針的利用
struct Data
{
Data(unsigned int,OrderedStaticCreatorFunc*, Creator);
unsigned int longevity;
OrderedStaticCreatorFunc* object;
Creator creator;
};
void OrderedStaticManagerClass::createObjects()
{
for(unsigned int longevity=max_longevity_; longevity>=min_longevity_; longevity--)
{
for(unsigned int i=0; i<staticObjects_.size(); i++)
{
Data cur = staticObjects_.at(i);
if(cur.longevity==longevity)
( (*cur.object).*cur.creator )();
}
}
}
Data中存放着成員對象object,並且還存放着該成員對象的成員函數指針creattor,把這個Data放在了一個vector中
然後調用方法( (*cur.object).*cur.creator )();。看着多麼奇怪的用法,實際上和普通函數調用一樣,只是它把它完全抽象化了
另外看一下create方法
void createObject()
{
Private::OrderedStaticBase<T>::SetLongevity(new T(para_()));
}
void createObject()
{
Private::OrderedStaticBase<T>::SetLongevity(new T(para_));
}
void createObject()
{
Private::OrderedStaticBase<T>::SetLongevity(new T);
}
private:
P1 para_;
Func para_;
各個對象的create方法都不同,但是可以都放在createobject中,然後將para在構造函數中傳入,保存下來
para_也不一定就是類型名字,也可以使函數!比如
Loki::OrderedStatic<1, std::string, std::string(*)() > s1( &func ); 只要支持將該函數返回值放到T的構造函數中就可以編譯通過就行。
我們要充分利用函數指針,不管是成員函數,仿函數,全局函數都可以利用
3、最大值最小值問題
這個比較簡單,不過開始看也會有迷惑
設置壽命期函數接口,每個函數壽命期1~max都不知道,我們保存一個最小壽命期,一個最大壽命期。這樣方便我們後續析構for循環調用。
min_longevity_,max_longevity_就是這兩個參數,那這兩個參數默認賦值多少合適呢?一下是loki的初始化賦值
OrderedStaticManagerClass::OrderedStaticManagerClass() :
staticObjects_(),
max_longevity_(std::numeric_limits<unsigned int>::min()), //
min_longevity_(std::numeric_limits<unsigned int>::max()) //
{
}
開始還以爲代碼是不是寫錯了,寫反了?
故意這樣的,max需要保存各個全局對象中的max,min需要保存全局對象中的min。這樣可以保證全局對象的值肯定小於min_longevity_,然後將全局對象的longervity賦值給min_longevity_(見下面的registerObject)。如果我們把min,max都設置成0,min可能就真的是0了,而實際上各個全局對象中的最小longervity是大於0的。
這樣也保證了後面的for如果沒有值能夠直接退出。因爲默認情況下min大於max
void OrderedStaticManagerClass::registerObject(unsigned int l, OrderedStaticCreatorFunc* o,Creator f)
{
staticObjects_.push_back(Data(l,o,f));
if(l>max_longevity_) max_longevity_=l;
if(l<min_longevity_) min_longevity_=l;
}