C++ 函数级静态变量何时分配/初始化?
我非常确信全局声明的变量在程序开始时被分配(并初始化,如果适用的话)C++ 函数级静态变量何时分配/初始化?,c++,variables,C++,Variables,我非常确信全局声明的变量在程序开始时被分配(并初始化,如果适用的话) int globalgarbage; unsigned int anumber = 42; #include < string> using namespace std; class test { public: test(const char *name) : _name(name) { cout << _name <<
int globalgarbage;
unsigned int anumber = 42;
#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;
}
但是在函数中定义的静态函数呢
void doSomething()
{
static bool globalish = true;
// ...
}
#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;
}
什么时候分配
globalish
的空间?我在猜节目什么时候开始。但是它也被初始化了吗?还是在第一次调用doSomething()
时对其进行初始化?静态变量在代码段内分配——它们是可执行映像的一部分,因此映射到已初始化的映像中
#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;
}
函数范围内的静态变量被视为相同的,作用域纯粹是一个语言级构造
#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;
}
因此,可以保证静态变量将被初始化为0(除非您指定其他内容),而不是未定义的值
#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;
}
您还可以利用初始化的一些其他方面——例如,共享段允许同时运行的可执行文件的不同实例访问相同的静态变量
#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;
}
<>在C++(全局范围)中,静态对象在C运行库的控制下,将它们的构造函数称为程序启动的一部分。在Visual C++中,至少可以用Prima.</P> < P>控制对象初始化的顺序,我对此感到好奇,于是编写了以下测试程序,并用G+4.4.1.2P/<
include <iostream>
#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;
};
test t("global variable");
void f()
{
static test t("static variable");
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;
}
#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;
}
所有静态变量的内存在程序加载时分配。但是本地静态变量是在第一次使用时创建和初始化的,而不是在程序启动时。关于这方面有一些很好的读物,一般来说,还有静力学。一般来说,我认为其中一些问题取决于实现,特别是如果您想知道这些东西在内存中的位置。编译器将在程序加载时分配函数
foo
中定义的静态变量,但编译器也会添加一些附加指令(机器代码)对于函数foo
,第一次调用该函数时,该附加代码将初始化静态变量(例如,如果适用,调用构造函数)
#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;
}
@亚当:编译器的这种幕后代码注入就是你看到结果的原因
#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;
}
还是在首次调用doSomething()时初始化
#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;
}
是的。除其他外,这允许您在适当的时候初始化全局访问的数据结构,例如在try/catch块内。例如,代替
int foo = init(); // bad if init() throws something
int main() {
try {
...
}
catch(...){
...
}
}
#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;
}
你可以写
int& foo() {
static int myfoo = init();
return myfoo;
}
#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;
}
并在try/catch块中使用它。在第一次调用时,变量将被初始化。然后,在第一个和下一个调用中,它的值将返回(以引用)。 < P>一些有关C++标准的相关内容:
#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;
}
3.6.2非本地对象的初始化[basic.start.init]
1.
具有静态存储的对象的存储
持续时间(basic.stc.static)应为零初始化(dcl.init)
在进行任何其他初始化之前。对象
具有静态存储持续时间的吊舱类型(基本类型)
应使用常量表达式(expr.const)初始化
在进行任何动态初始化之前初始化。
中定义了静态存储持续时间的命名空间范围的对象
应使用相同的翻译单元并动态初始化
按其定义在中的显示顺序初始化
翻译股。[注:dcl.init.aggr描述了
聚合成员初始化的顺序
stmt.dcl中描述了本地静态对象的初始化。]
#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;
}
[下面的更多文本为编译器编写者添加更多自由]
#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;
}
6.7声明声明[stmt.dcl]
#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;
}
4.
具有的所有本地对象的零初始化(dcl.init)
静态存储持续时间(basic.stc.static)在
任何其他初始化都会发生。局部对象
带静态存储持续时间的吊舱类型(基本类型)
使用常量表达式初始化在其
块是首先输入的。允许执行一个实现
使用静态存储对其他本地对象进行早期初始化
与实现相同条件下的持续时间
允许使用静态存储静态初始化对象
命名空间范围中的持续时间(basic.start.init)。否则
控件第一次通过对象时初始化对象
宣言;这样的对象被认为是在
完成其初始化。如果初始化通过退出
引发异常时,初始化未完成,因此将
下次控件进入声明时重试。如果控件在对象运行时重新输入声明(递归)
初始化后,行为未定义。[示例:
#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;
}
--[结束示例]
#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;
}
5.
具有静态存储持续时间的本地对象的析构函数将
当且仅当构造变量时才执行。
[注意:basic.start.term描述本地
具有静态存储持续时间的对象将被销毁。]
#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;
}
我尝试再次测试来自Adam Pierce的代码,并添加了另外两种情况:类中的静态变量和POD类型。我的编译器是Windows操作系统(MinGW-32)中的g++4.8.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;
}
- 结论(对于g++,Windows环境):
#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; }
- 全局变量和类中的静态成员:在进入main函数之前调用构造函数(1)
- 局部静态变量:仅当执行第一次到达其声明时才调用构造函数
- 如果<强