C++ - 全局静态对象和局部静态对象的构造函数调用不同?
Posted
技术标签:
【中文标题】C++ - 全局静态对象和局部静态对象的构造函数调用不同?【英文标题】:C++ - Constructor call of global static object and local static object is different? 【发布时间】:2013-12-01 05:45:04 【问题描述】:这里有同样的问题:When exactly is constructor of static local object called?
但它只提到了本地静态对象,所以我想为全局静态对象再添加一个案例。
假设我们有 2 个这样的示例代码:
考试1.本地静态==========
class Mix
Mix() //the ctor code
;
Mix& globalFunction()
static Mix gMix; // when its ctor execute ?
return gMix;
考试 2. 全局静态 ==========
class Mix
Mix() //the ctor code
static MyClass MReen; // when its ctor execute ?
;
//initialization static var
MyClass Mix::MReen = 0 ;
上面 2 个静态对象的“构造函数代码”究竟是什么时候执行的?
g++(在 Linux 上运行)和 VC++ 编译器有何不同?
谢谢
【问题讨论】:
Mix::MReen = 0
是赋值,而不是初始化,在全局范围内是不允许的。将 MyClass
添加到它以使其初始化,尽管初始化为 0 是多余的。
答案在这里:***.com/questions/246564/…
谢谢,我缺少 MyClass。已更新。
【参考方案1】:
我尝试再次测试来自here Adam Pierce 的代码,并添加了另外两种情况:类中的静态变量和 POD 类型。我的编译器是 g++ 4.8.1,在 Windows 操作系统(MinGW-32)中。 结果是类中的静态变量与全局变量相同。它的构造函数会在进入主函数之前被调用。
结论(针对g++,Windows环境):
-
全局变量和类中的静态成员:在进入main函数之前调用构造函数(1)。
局部静态变量:构造函数仅在执行第一次到达其声明时才被调用。
如果局部静态变量是POD类型,那么在进入main函数之前也会被初始化(1)。
POD 类型示例:static int number = 10;
(1):正确的状态应该是:“在调用来自同一个翻译单元的任何函数之前”。但是,为了简单起见,如下例所示,那么它就是main函数。
包括
#include < string>
using namespace std;
class test
public:
test(const char *name)
: _name(name)
cout << _name << " created" << endl;
~test()
cout << _name << " destroyed" << endl;
string _name;
static test t; // static member
;
test test::t("static in class");
test t("global variable");
void f()
static test t("static variable");
static int num = 10 ; // POD type, init before enter main function
test t2("Local variable");
cout << "Function executed" << endl;
int main()
test t("local to main");
cout << "Program start" << endl;
f();
cout << "Program end" << endl;
return 0;
结果:
static in class created
global variable created
local to main created
Program start
static variable created
Local variable created
Function executed
Local variable destroyed
Program end
local to main destroyed
static variable destroyed
global variable destroyed
static in class destroyed
有人在 Linux 环境中测试过吗?
【讨论】:
【参考方案2】:-
在函数中声明的局部静态变量在第一次调用该函数之前被初始化。您可以在此处https://***.com/a/58804/747050 阅读有关 C++ 标准这方面的更多信息。
全局静态变量在main()
之前初始化,但如果您有多个文件,即使在一个编译器中也不会保证顺序。以下是相关答案:http://www.parashift.com/c++-faq/static-init-order.html,Can the compiler deal with the initialization order of static variables correctly if there is dependency?
附言您可以通过一个技巧来保证 const static 的顺序:
int YourClass::YourStaticVar()
static const int value = 0;
return value;
【讨论】:
许多编译器在链接期间按照对象文件的顺序来创建静态对象。如果是这样,则应在编译器的文档中提及。 你的第一句话是什么意思?调用什么函数? @EJP,在本例中为 globalFunction() 调用。 那我相信你错了。保证在调用函数之前已经执行,但不一定是“第一次调用”。 嗨,有人告诉我,本地静态对象的构造函数(这里是Mix)只有在函数globalFunction被调用时才会被调用第一次。但是其他一些想法告诉构造函数在main之前调用,它应该在dll加载期间。那么,什么是正确的呢?以上是关于C++ - 全局静态对象和局部静态对象的构造函数调用不同?的主要内容,如果未能解决你的问题,请参考以下文章
新手小白学JAVA static final 静态/构造/局部代码块之间的关系