C ++初始化静态数组

时间:2017-02-06 14:16:20

标签: c++ arrays static

我不确定这是否可行。从我看到的所有示例中,数组在{ }括号内定义,但在我的情况下,它是不可能的。

我要做的是将它保留在我的绘图功能中,以绘制缓慢增加大小的多个圆圈。

使用调试器得到的是每次循环命中时都会重置静态数组。

我也试过像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
 }

4 个答案:

答案 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()};