static对象:一旦被创建,就一直存在,直到程序退出。
根据静态对象的位置不同,可以分为两类:non-local static object与local static object
具体来说:
local static object:指函数中用static修饰符修饰的object
生命期起始时间:在函数第一次调用时构造初始化。
生命期终止时间:程序结束
non-local static object:包括全局objects,在名词空间范围的objects,类中用static修饰符修饰的objects
生命期起始时间:在main函数调用之前被构造初始化。
生命期终止时间:程序结束
注意:在同一个文件或不同编译单元(不同文件)中,如果存在多个non-local static object,它们都是在主函数调用之前被构造的,但是它们之间的构造顺序时不定的。即对编译器来说,静态成员对象之间的初始化顺序和析构顺序是一个未定义的行为。
因此,不能用某个non-local static object去初始化non-local static object,无论这两个non-local static object在不在同一个编译单元中。
下面给出一个处在两个编译单元(CPP文件)中的non-local static object相互引用的情况:
class FileSystem
{
public: …
std::size_t numDisks() const;
};
extern FileSystem tfs;
//另一编译单元
class Directory
{
public:
Directory(params);
};
Directory::Directory(params)
{
std::size_t disks = tfs.numDisks();//使用另一个编译单元的静态变量
}
Directory tempDir (params);
由于编译器没有定义
non-local static object之间的构造顺序,所以有可能类tfs还没有被构造,所以程序可能会报错。
解决方法:用local static对象替换non-local static对象。
C++保证,函数内的local static 对象会在该函数被调用期间,首次遇上该对象定义式时被初始化。
class FileSystem {…};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
//另一编译单元
class Directory {…};
Directory::Directory (params)
{
std::size_t disks = tfs().numDisks();//执行函数tfs时,对象fs肯定会被构造。
};
Directory& tempDir()
{
static Directory td;
return td;
}