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