编译时初始化

看代码的时候看到一个这样的函数:

A* A::GetInstance()
{
    static A s_ASingleton;
    return &s_ASingleton;
    test;
}

显然这是一个单例模式的Get方法,但是我之前没有见过这种用法,于是就有了以下疑问:

这个函数多次调用的话,不会重复初始化s_HwEnvironmentSingleton导致效率很低吗?

经过上网调查,发现函数中的static变量是只初始化一次的,于是又有了以下疑问:

程序怎么判断这是第一次调用?

基于这个疑问,我又写了个测试程序,查看了它的编译结果

int test2(){
    static int a = 3;
    ++a;
    return a;
}

其编译结果如下:

push    rbp
mov     rbp, rsp
mov     eax, DWORD PTR test2()::a[rip]
add     eax, 1
mov     DWORD PTR test2()::a[rip], eax
mov     eax, DWORD PTR test2()::a[rip]
pop     rbp
ret

奇怪的是,这个函数中根本没有对a初始化。

那么static变量是什么时候初始化的呢?

C++中static变量的初始化_lucky-billy的博客-CSDN博客_c++静态变量初始化

c++ 全局变量初始化的一点总结 - twoon - 博客园

刚刚的汇编只对简单类型有效,而对HwEnviroment并不适用。

经过试验,可以得到准确结论

#include<iostream>
using namespace std;

class A{
public:
    static A* getInstance(){
        cout<<"调用getInstance"<<endl;
        static A aim;
        return &aim;
    }
    A(){
        cout<<"A被构造!"<<endl;
    };
    virtual ~A(){
        cout<<"A被析构!"<<endl;
    };
    int test(){
        return 1;
    };
};

int main(void){
    cout<<"进入main函数"<<endl;
    int a = A::getInstance()->test();
    cout<<a<<endl;
    cout<<A::getInstance()->test()<<endl;
    return 0;
}

执行结果如下:

进入main函数
调用getInstance
A被构造!
1
调用getInstance
1
A被析构!

结论:

s_HwEnvironmentSingleton在GetInstance()第一次调用时被初始化,只初始化一次,此后的调用不会再次初始化。