我不确定这是否可行。从我看到的所有示例中,数组在{ }
括号内定义,但在我的情况下,它是不可能的。
我要做的是将它保留在我的绘图功能中,以绘制缓慢增加大小的多个圆圈。
使用调试器得到的是每次循环命中时都会重置静态数组。
我也试过像static Rect rc[5] = {}
void fun_called_every_five_seconds() {
static Rect rc[5];
for (int i = 0; i < count; i++) {
int x = rand()%400;
int y = rand()%400;
int r = rand()%200;
rc[i] = Rect (x,y,r,r);
}
rc[0].X += 50;
// I check value of rc[0].X right here
}
答案 0 :(得分:2)
每次循环命中时都会重置静态数组
是的,您的循环显式重置静态数组。
最小的改变是只运行一次初始化循环:
void for_fun_called_every_five_seconds() {
static Rect rc[5];
static bool init = false;
if (!init) { // this only happens once
init = true;
for (int i = 0; i < count; i++) {
int x = rand()%400;
int y = rand()%400;
int r = rand()%200;
rc[i] = Rect (x,y,r,r);
}
}
rc[0].X += 50;
// I check value of rc[0].X right here
}
但这非常难看,而且不必要地推理。喜欢像
这样的东西class Circles {
Rect rc[5];
public:
Circles() {
for (int i = 0; i < count; i++) {
int x = rand()%400;
int y = rand()%400;
int r = rand()%200;
rc[i] = Rect (x,y,r,r);
}
}
void for_fun_called_every_five_seconds() {
// should this also be in a loop,
// ie. each rc[i] gets increased?
rc[0].X += 50;
// I check value of rc[0].X right here
}
};
答案 1 :(得分:2)
这里没有什么可惊讶的。每次调用函数时,其所有代码都从其参数执行。
这里唯一的例外是static
变量的初始化,它保证在程序的生命周期内只运行一次(从C ++ 11开始也是线程安全的)。
变量的初始化仅在其定义期间发生,在您为变量提供此上下文中的名称的行上。之后的所有代码都是简单的#34;变异&#34;你的变量给它你想要的值:它不是初始化。
这里有两个解决方案。您可以将std::call_once
与lambda(请参阅http://en.cppreference.com/w/cpp/thread/call_once)一起使用以进行&#34;初始化&#34;代码只运行一次。
或者你以某种方式将所有代码放在变量定义的一行中。对于C风格的数组可能会很复杂,但std::array
可能很复杂,可以很容易地从函数返回并用于初始化std::array
。
std::array<Rect, 5> initialize_rc() {
std::array<Rect, 5> rc;
for (int i = 0; i < count; i++) {
int x = rand()%400;
int y = rand()%400;
int r = rand()%200;
rc[i] = Rect (x,y,r,r);
}
return rc;
}
void for_fun_called_every_five_seconds() {
static std::array<Rect, 5> rc = initialize_rc();
rc[0].X += 50;
// I check value of rc[0].X right here
}
答案 2 :(得分:2)
您可以拆分代码并将数组初始化放在其他位置:
auto make_rect_array() {
std::array<Rect, 5> rc;
for (int i = 0; i < count; i++) {
int x = rand()%400; // you may want better random
int y = rand()%400;
int r = rand()%200;
rc[i] = Rect (x,y,r,r);
}
return rc;
}
然后,只需在你的函数中调用它:
void fun_called_every_five_seconds() {
static auto rc = make_rect_array();
rc[0].X += 50;
// I check value of rc[0].X right here
}
这样,您就不会在代码中引入额外的分支,它看起来更干净,而且线程安全。
答案 3 :(得分:1)
另一个答案很好,只要整个事情不必是线程安全的。
如果初始化必须是线程安全的,那么除了将所有内容都推送到声明中之外别无选择。
但是,可以使用辅助类来最小化输入:
class RandomRect : public Rect {
public:
RandomRect() : RandomRect(rand() % 400, rand() % 400, rand % 200) {}
RandomRect(int x, int y, int r) : Rect(x, y, r, r) {}
};
// ... Then, initialize the static array as follows:
static Rect rc[5]={RandomRect(), RandomRect(), RandomRect(),
RandomRect(), RandomRect()};