C++ 中类静态变量的生命周期是多少?
如果我有一个名为 Test :: 的类,
class Test
{
static std::vector<int> staticVector;
};
staticVector 何时被构造以及何时被破坏?
是通过 Test 类的第一个对象的实例化,还是像常规静态变量一样?
为了澄清一下,在阅读《编程语言概念》(Sebesta Ch-5.4.3.1) 后,我想到了这个问题,它说:::
请注意,当 static 修饰符 出现在声明中 C++ 中类定义中的变量, Java和C#,没有关系 变量的生命周期。 在那里面 上下文,这意味着变量是 类变量,而不是 实例变量。 多重用途 保留字的定义可能会令人困惑 特别是对于那些学习 语言。
你明白了吗? :(
If I have a class called Test ::
class Test
{
static std::vector<int> staticVector;
};
when does staticVector get constructed and when does it get destructed ?
Is it with the instantiation of the first object of Test class, or just like regular static variables ?
Just to clarify, this question came to my mind after reading Concepts of Programming Languages (Sebesta Ch-5.4.3.1) and it says ::
Note that when the static modifier
appears in the declaration of a
variable in a class definition in C++,
Java and C#, it has nothing to do with
the lifetime of the variable. In that
context, it means the variable is a
class variable, rather than an
instance variable. The multiple use
of a reserved word can be confusing
particularly to those learning the
language.
did you understand? :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我也想写一些关于初始化的文本,稍后我可以链接到它。
首先列出可能性。
Namespace Static
示例:
以下程序打印
A(1) A(2)
而以下程序基于同一类,打印
A(2) A (1)
假设有一个翻译单元,其中
msg
定义如下然后下面打印
abc
。 请注意,p
接收动态初始化。 但因为msg
的静态初始化(char const*
是 POD 类型,"abc"
是地址常量表达式)发生在这之前,这很好,并且msg
保证被正确初始化。Class Static
- Behave like namespace statics.
- There is a bug-report on whether the compiler is allowed to initialize class statics on the first use of a function or object of its translation unit too (after main). The wording in the Standard currently only allows this for namespace scope objects - but it seems it intends to allow this for class scope objects too. Read [Objects of Namespace Scope](http://groups.google.com/group/comp.std.c++/browse_thread/thread/28cfef85456512c8).
- For class statics that are member of templates the rule is that they are only initialized if they are ever used. Not using them will not yield to an initialization. Note that in any case, initialization will happen like explained above. Initialization will not be delayed because it's a member of a template.
Local Static
- For local statics, special rules happen.
- POD type objects initialized with constant expression are initialized before their block in which they are defined is entered.
- Other local static objects are initialized at the first time control passes through their definition. Initialization is not considered to be complete when an exception is thrown. The initialization will be tried again the next time.
示例:下面的程序打印
0 1
:在上述所有情况下,在某些有限的情况下,对于一些不需要静态初始化的对象,编译器可以静态初始化它,而不是动态初始化它。 这是一个棘手的问题,请参阅 这个答案了解更详细的示例。
另请注意,销毁顺序是对象构造完成的确切顺序。 这是很常见的情况,在 C++ 中的各种情况下都会发生,包括破坏临时对象。
I want to write some text about initializaton too, which i can later link to.
First the list of possibilities.
Namespace Static
std::terminate
is called.Examples:
The following program prints
A(1) A(2)
And the following, based on the same class, prints
A(2) A(1)
Let's pretend there is a translation unit where
msg
is defined as the followingThen the following prints
abc
. Note thatp
receives dynamic initialization. But because the static initialization (char const*
is a POD type, and"abc"
is an address constant expression) ofmsg
happens before that, this is fine, andmsg
is guaranteed to be correctly initialized.Class Static
- Behave like namespace statics.
- There is a bug-report on whether the compiler is allowed to initialize class statics on the first use of a function or object of its translation unit too (after main). The wording in the Standard currently only allows this for namespace scope objects - but it seems it intends to allow this for class scope objects too. Read [Objects of Namespace Scope](http://groups.google.com/group/comp.std.c++/browse_thread/thread/28cfef85456512c8).
- For class statics that are member of templates the rule is that they are only initialized if they are ever used. Not using them will not yield to an initialization. Note that in any case, initialization will happen like explained above. Initialization will not be delayed because it's a member of a template.
Local Static
- For local statics, special rules happen.
- POD type objects initialized with constant expression are initialized before their block in which they are defined is entered.
- Other local static objects are initialized at the first time control passes through their definition. Initialization is not considered to be complete when an exception is thrown. The initialization will be tried again the next time.
Example: The following program prints
0 1
:In all the above cases, in certain limited cases, for some objects that are not required to be initialized statically, the compiler can statically initialize it, instead of dynamically initializing it. This is a tricky issue, see this answer for a more detailed example.
Also note that the order of destruction is the exact order of the completion of construction of the objects. This is a common and happens in all sort of situations in C++, including in destructing temporaries.
与常规静态(全局)变量完全相同。
Exactly like regular static (global) variables.
它是在全局变量被构造的同时被构造的,并且也与全局变量一起被破坏。
It gets constructed at the same time the global variables get constructed and destructed along with the globals as well.
简单来说:
静态成员变量是在构造全局变量时构造的。 全局变量的构造顺序没有定义,但它发生在进入主函数之前。
当全局变量被销毁时,就会发生销毁。
全局变量按照它们构造的相反顺序被销毁; 退出主函数后。
问候,
Ovanes
P.S.:我建议看一下 C++ 标准,它解释(定义)了如何以及何时构造或析构全局或静态成员变量。
PPS:您的代码只声明了一个静态成员变量,但没有初始化它。 要初始化它,您必须在编译单元之一中编写:
std::vector Test::staticVector;
或
std::vector Test::staticVector=std::vector(/* 这里是 ctor 参数 */);
Simply speaking:
A static member variable is constructed when the global variables are constructed. The construction order of global variables is not defined, but it happens before the main-function is entered.
Destruction happens when global variables are destroyed.
Global variables are destroyed in the reversed order they were constructed; after exiting the main-function.
Regards,
Ovanes
P.S.: I suggest to take a look at C++-Standard, which explains (defines) how and when global or static member variables are constructed or destructed.
P.P.S.: Your code only declares a static member variable, but does not initialize it. To initialize it you must write in one of the compilation units:
std::vector Test::staticVector;
or
std::vector Test::staticVector=std::vector(/* ctor params here */);
一些特定的 VC++ 信息(如果您正在使用这些信息):
这是您编译的大多数程序的实际入口点(它是调用 Main/Winmain 函数的函数)。
此外,它还负责初始化整个C运行时支持(例如您需要它来使用malloc)。
statics.h是合法且安全的:
... MyClass 声明 ...
静态常量 int a;
静态 int b;
静态 int ar[];
}
静态.cpp:
Some specific VC++ information in case that's what you're using:
This is the actual entry point of most programs you compile (it is the function which calls your Main/Winmain function).
In addition, it is responsible for initializing the entire C runtime support (for example you need it to use malloc).
statics.h:
... MyClass declaration ...
static const int a;
static int b;
static int ar[];
}
statics.cpp: