OrderedStatic

OrderedStatic實現了對象的生命期控制,根據對象壽命


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;
        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章