- #include <iostream>
- using namespace std;
- /* Place holder for thread synchronization mutex */
- class Mutex
- { /* placeholder for code to create, use, and free a mutex */
- };
- /* Place holder for thread synchronization lock */
- class Lock
- { public:
- Lock(Mutex& m) : mutex(m) { /* placeholder code to acquire the mutex */ }
- ~Lock() { /* placeholder code to release the mutex */ }
- private:
- Mutex & mutex;
- };
- class Singleton
- { public:
- static Singleton* GetInstance();
- int a;
- private:
- Singleton(int _a) : a(_a) { cout << "In Ctor" << endl; }
- ~Singleton() { cout << "In Dtor" << endl; }
- static Mutex mutex;
- // Not defined, to prevent copying
- Singleton(const Singleton& );
- Singleton& operator =(const Singleton& other);
- };
- Mutex Singleton::mutex;
- Singleton* Singleton::GetInstance()
- {
- Lock lock(mutex);
- cout << "Get Inst" << endl;
- // Initialized during first access
- static Singleton inst(1);
- return &inst;
- }
- int main()
- {
- Singleton* singleton = Singleton::GetInstance();
- cout << "The value of the singleton: " << singleton->a << endl;
- return 0;
- }
- // Initialized during first access
- static Singleton inst(1);
- 00411F8C mov eax,dword ptr [$S1 (435234h)]
- 00411F91 and eax,1
- 00411F94 jne Singleton::GetInstance+0B4h (411FC4h)
- 00411F96 mov eax,dword ptr [$S1 (435234h)]
- 00411F9B or eax,1
- 00411F9E mov dword ptr [$S1 (435234h)],eax
- 00411FA3 mov byte ptr [ebp-4],1
- 00411FA7 push 1
- 00411FA9 mov ecx,offset inst (435230h)
- 00411FAE call Singleton::Singleton (411799h)
- 00411FB3 push offset `Singleton::GetInstance'::`2'::`dynamic atexit destructor for 'inst'' (42D370h)
- 00411FB8 call @ILT+480(_atexit) (4111E5h)
- 00411FBD add esp,4
- 00411FC0 mov byte ptr [ebp-4],0
- return &inst;
- 00411FC4 mov dword ptr [ebp-0E0h],offset inst (435230h)
- 00411FCE mov dword ptr [ebp-4],0FFFFFFFFh
- 00411FD5 lea ecx,[ebp-14h]
- 00411FD8 call Lock::~Lock (41178Fh)
- 00411FDD mov eax,dword ptr [ebp-0E0h]
我们debug这个代码一下,在断点执行到static Singleton inst(1);的时候看到了这样的汇编语句。汇编语句中括号里面的数值是debug时候的地址。可以看到那个JNE,当条件满足的时候可以跳转到411FC4h,也就是 return &inst; 的位置,如果条件不满足就依次执行构造函数和atexit的设置。简单点的说就是,这里的inst是在程序第一次执行到这条语句的时候做初始化的。而不是main函数之前,loading阶段的。这个可能是很常见的问题还是让自己小小的吃惊了一把。
既有此,想到了另一个形式变量, 如果我在这个函数里面加入一个static int temp = 1;会怎么样呢?这个是在什么时候分配呢?说干就干,这时候我们看到的汇编语句没有任何的变化。(只是显示这样一条C++的语句)。所以这一类的变量的初始化可以说和刚才的顺序是不同的。所以原书中对局部静态变量有了精彩的论述
int Fun()
{
static int x = 100;
return ++x;
}
In this case, x is initialized before any code in the program is executed, most likely at load time. For all that Fun can tell when first called, x has been 100 since time immemorial. In contrast, when the initializer is not a compile-time constant, or the static variable is an object with a constructor, the variable is initialized at runtime during the first pass through its definition.
也就是说,局部静态变量如果是基本数据类型,而且赋值语句的右边是编译期常量的话,这个局部变量的初始化实在程序加载期间就完成的。但是如果是那些类的对象(有构造函数)的局部静态变量就是在第一次执行此语句的时候完成初始化的,当然这里还包括基本数据类型的赋值语句右侧是变量的情况。
举个例子有这样的函数
- int Func(int x)
- {
- static int temp = x*x;
- }
可以预见的是这样的temp的初始化是在一次这个函数被调用的时候发生的,不然的话也确实没有办法提前初始化他。
有了以上的论述在发现,确实这样一个Mutex还是有存在的必要性的:)