在一个指定的翻译单元中,静态对象的初始化顺序严格按照对象在该单元中
出现的顺序
而清除的顺序则与初始化的顺序正好相反
但是,对于作用域为多个翻译单元的静态对象来说,不能保证严格的初始化顺序,
也没有办法来指定这种顺序
由Jerry Schwarz在创建iostream库 cin,cout和cerr是静态的且定义在不同的
文件中 时首创的一种技术
这一技术要求在库头文件中加上一个额外的类
这个类负责库中的静态对象的动态初始化
//: C10:Initializer.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Static initialization technique
#ifndef INITIALIZER_H
#define INITIALIZER_H
#include <iostream>
extern int x; // Declarations, not definitions
extern int y;
class Initializer {
static int initCount;
public:
Initializer() {
std::cout << "Initializer()" << std::endl;
// Initialize first time only
if(initCount++ == 0) {
std::cout << "performing initialization"
<< std::endl;
x = 100;
y = 200;
}
}
~Initializer() {
std::cout << "~Initializer()" << std::endl;
// Clean up last time only
if(--initCount == 0) {
std::cout << "performing cleanup"
<< std::endl;
// Any necessary cleanup here
}
}
};
// The following creates one object in each
// file where Initializer.h is included, but that
// object is only visible within that file:
static Initializer init;
#endif // INITIALIZER_H ///:~
x,y的声明只是表明这些对象的存在,并没有它们分配存储空间
下面是一个包含x、y和init_Count定义的文件
//: C10:InitializerDefs.cpp {O}
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Definitions for Initializer.h
#include "Initializer.h"
// Static initialization will force
// all these values to zero:
int x;
int y;
int Initializer::initCount;
///:~
当一个文件包含头文件时,它的init静态实例静态实例也放在文件中
假设库的使用者产生了两个其他的文件
//: C10:Initializer.cpp {O}
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Static initialization
#include "Initializer.h"
///:~
以及
//: C10:Initializer2.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
//{L} InitializerDefs Initializer
// Static initialization
#include "Initializer.h"
using namespace std;
int main() {
cout << "inside main()" << endl;
cout << "leaving main()" << endl;
getchar();
} ///:~
现在哪个法院单元先初始化都没有关系
当第一次包含Initializer.h的翻译单元被初始化时,initCount为零,这时
初始化就已经完成了
用内建类型作为全局静态对象,这种方法也可以用于类,但其对象必须用
initializer类动态初始化
输出
Initializer()
performing initialization
Initializer()
Initializer()
inside main()
leaving main()