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
我有一个问题,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