【发布时间】:2016-02-01 06:56:10
【问题描述】:
这本书Object oriented programming in c++ by Robert Lafore 说,
静态局部变量具有自动局部变量的可见性 变量(即在包含它的函数内部)。然而,其 生命周期与全局变量的生命周期相同,只是它 直到第一次调用函数才存在 包含它。此后,它终生存在 程序
第一次调用函数后开始存在是什么意思?静态本地的存储空间是在程序加载到内存时分配的。
【问题讨论】:
这本书Object oriented programming in c++ by Robert Lafore 说,
静态局部变量具有自动局部变量的可见性 变量(即在包含它的函数内部)。然而,其 生命周期与全局变量的生命周期相同,只是它 直到第一次调用函数才存在 包含它。此后,它终生存在 程序
第一次调用函数后开始存在是什么意思?静态本地的存储空间是在程序加载到内存时分配的。
【问题讨论】:
在输入 main 之前分配存储空间,但是(例如)如果静态对象有一个带有副作用的 ctor,这些副作用可能会延迟到第一次调用该函数之前。
但是,请注意,不一定是这种情况。只需要在输入该块之前进行常量初始化(不一定只是因为执行“跨越”该定义)。同样,在某些情况下,允许实现比所需的更早初始化其他块范围静态变量(如果您想了解情况的血腥细节,可以查看 [basic.start.init] 和 [stmt.dcl] ,但它基本上归结为:只要它不影响初始化它的值。例如,如果你有类似的东西:
int i;
std::cin >> i;
{
static int x = i;
...在进入块之前,实现将无法初始化x,因为在它们之前不会知道初始化它的值。另一方面,如果你有:
{
static int i = 0;
...实现可以尽可能早地执行初始化(并且大多数将/将基本上在编译时执行这样的初始化,因此它不会涉及执行任何指令完全在运行时)。然而,即使对于不太简单的情况,在逻辑可能的情况下也允许更早的初始化(例如,该值不是来自先前的执行)。
【讨论】:
在 C++ 中,对象的存储持续时间(当为它分配原始内存时)和对象的生命周期是两个独立的概念。作者在谈到物体的“形成”时,显然是指后者。
在一般情况下,为一个对象分配存储空间以使其“存在”是不够的。具有非平凡初始化的对象的生命周期在其初始化完成后开始。例如,具有非平凡构造函数的类的对象在其构造函数完成执行之前不会正式“存活”。
当控件第一次越过声明时执行静态本地对象的初始化。在此之前,该对象并不正式存在,即使它的内存已经分配。
请注意,作者的描述并非刻意精确。仅仅调用包含声明的函数是不够的。控件必须通过对象的声明才能开始其生命周期。如果函数包含分支,则不一定在第一次调用函数时发生。
对于简单初始化的对象(如int 对象),存储持续时间和生命周期之间没有区别。对于此类对象,只需分配内存即可。但一般情况下,单独分配内存是不够的。
【讨论】:
这意味着函数内的静态变量在第一次调用该函数之前不会被初始化(由构造函数或赋值运算符)。
【讨论】:
只要调用包含静态局部变量的函数,就会初始化静态局部变量。
【讨论】: