class 的 C++ 静态成员在构造函数之后初始化

C++ Static members of a class are initialized after constructor

我有一个问题,class 的静态成员没有在构造函数之前初始化。难道我做错了什么?它是 G++ 中的错误吗? 有什么解决方法吗?

g++ --version : (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
我也使用 Eclipse 作为我的 IDE,但我只是将静态库 headers 复制到 /usr/include/StaticTestLib/InitTest.h,将库复制到 /usr/lib/x86_64-linux-gnu/libStaticTestLib.a

请注意,只有当保存数据的 object 在 main 之前定义并且 class 在静态库中时才会发生这种情况。

静态库header(静态库本身命名为StaticTestLib):

InitTest.h
#include <iostream>
namespace StaticTestLib  {
    class notifier_header{
    public:
        notifier_header(){
            std::cout<<"static var init"<<std::endl;
        }
    };

    class InitTest {
    public:
        static notifier_header _header_notifier;
        InitTest();
        virtual ~InitTest();
    };    
}

静态库源文件:

InitTest.cpp
#include "InitTest.h"

namespace StaticTestLib  {
    notifier_header InitTest::_header_notifier;

    class notifier_cpp{
    public:
        notifier_cpp(){
            std::cout<<"code before constructor"<<std::endl;
        }
    }_notifier_in_cpp;

    InitTest::InitTest() {
        std::cout<<"constructor"<<std::endl;
    }

    InitTest::~InitTest() {
        std::cout<<"destructor"<<std::endl;
    }
}

这个节目:

StaticTest.cpp
#include <iostream>
#include <StaticTestLib/InitTest.h>

StaticTestLib::InitTest test;

int main() {
    std::cout << "program main" << std::endl;
    std::cout << "program end" << std::endl;
    return 0;
}

…输出:

constructor
static var init
code before constructor
program main
program end
destructor

但是这个程序:

#include <iostream>
#include <StaticTestLib/InitTest.h>

int main() {
    std::cout << "program main" << std::endl;
    StaticTestLib::InitTest test;
    std::cout << "program end" << std::endl;
    return 0;
}

…输出:

static var init
code before constructor
program main
contructor
program end
destructor

我的猜测是这与未定义不同编译单元中的静态对象初始化顺序有关。

main 中创建 test 对象的第二个代码片段很容易解释。静态初始化总是在任何代码执行之前发生,所以当你进入 main 时,你的 notifier_header 对象肯定已经创建。

现在,当您在 main 之前创建 test 时,您有两个静态对象。 notifier_header 对象不依赖于您的 InitTest:它在 class 范围内,但它存储在静态内存中。您似乎在 InitTest.cpp 中引用了 notifier_header,这是与 main 不同的编译单元。编译器可以自由地为这两个单元以任何顺序进行静态分配,前提是没有相互依赖性。

如果您的构造函数依赖于 notifier_header,您可以将其用作单例。创建一个 returns 静态对象实例的函数(下例中的 headerInstance),并在调用时创建对象:

#include <iostream>
namespace StaticTestLib  {
class notifier_header{
public:
    notifier_header(){
        std::cout<<"static var init"<<std::endl;
    }
};


class InitTest {
public:
    InitTest();
    virtual ~InitTest();
    notifier_header& headerInstance();
};

}

静态库源文件(InitTest.cpp)

#include "InitTest.h"

namespace StaticTestLib  {

class notifier_cpp{
public:
    notifier_cpp(){
        std::cout<<"code before constructor"<<std::endl;
    }
}_notifier_in_cpp;

InitTest::InitTest() {
    headerInstance();
    std::cout<<"constructor"<<std::endl;
}

InitTest::~InitTest() {
    std::cout<<"destructor"<<std::endl;
}

notifier_header& InitTest::headerInstance() {
    static notifier_header _header_notifier; // will only be constructed once
    return _header_notifier;
}

}

我得到的输出:

static var init
constructor
code before constructor
program main
program end
destructor