说我有一个C ++函数:
void foo(int x) {
static int bar = x;
}
如果我拨打foo(3)
然后拨打foo(4)
,我的理解是bar的值仍为3.为什么会这样?我理解为什么初始化的内存分配部分是多余的。但为什么这项任务也被忽略了?
答案 0 :(得分:6)
这不是“任务”。这是初始化。而且,根据C ++语言的规则,静态对象的初始化只执行一次 - 当控件第一次通过声明时。
在您的示例中,当bar
为x
时,控件会传递3
的声明。因此,使用bar
初始化3
。它永远不会被“重新初始化”,即调用foo(4)
根本不会影响bar
。如果您想在此之后更改bar
的值,则必须直接修改bar
。
答案 1 :(得分:2)
简短回答:因为标准是这么说的。
答案很长:那不是分配,而是初始化,而且它被忽略了,因为标准是这样说的。
答案 2 :(得分:0)
bar
的内存位置在第一次调用foo
之前无效,这是bar
实例化的时间。 bar
在实例化时会初始化为x
。之后对foo
的每次调用bar
都已经过实例化,因此已经初始化。
答案 3 :(得分:0)
这是静态变量的初始化,而不是为其赋值。话虽如此,如果你在第一个位置调用foo(3),bar的值总是为3。
答案 4 :(得分:0)
考虑一些不同的静态变量:
void foo(int x) {
static int bar = x;
static std::string s1 = "baz";
static std::string s2("baz");
static int i{2}; // C++11-style uniform initialization
}
你是否也认为s1
应该被分配"每次调用函数时值"baz"
?那么s2
呢?那么i
呢?
这些语句都不执行任何赋值,它们都是初始化,并且只执行一次。仅仅因为声明包含=
字符并不能使其成为作业。
为什么定义语言以这种方式工作的原因是使用本地静态变量来运行一次函数是很常见的:
bool doInit()
{
// run some one-time-only initialization code
// ...
return true;
}
void func() {
static bool init = doInit();
// ...
}
如果每次调用函数时init
再次分配一个值,那么doInit()
将被多次调用,并且无法运行一次性设置。
如果您想在每次调用时更改值,那很容易......只需更改它即可。但是,如果你不想希望它不断变化,那么如果语言按你所要求的方式运作,就没有办法做到这一点。
static const
局部变量:
void func() {
static const bool init = doInit();
// ...
}
哎呀,每次调用它时都会尝试更改init
的值。