静态int变量的std :: out_of_range

时间:2017-08-21 02:19:13

标签: c++ c++11 variables static int

我在一个基于dos的小游戏(课程项目)中使用静态变量作为make-shift计时器。变量在状态效果消失之前跟踪转数。这是代码:

for (auto &i : v) // <-- code that calls enemyAttack
    enemyAttack(i, p, str, i.attack);
break;

void enemyAttack(Enemy &e, playerObject &p, std::array<std::string, NUM_MESSAGES> &str, void(*a)(playerObject &p, std::array<std::string, NUM_MESSAGES> &str)) {
    int die = rand() % 100 + 1;
    int d = 1;

    a(p, str); // <-- Call function which causes the error

    ...
}

void batAttack(playerObject &p, std::array<std::string, NUM_MESSAGES> &str) {
    static int time = 2;
    static bool bit = false;

    if (rand() % 10 < CHANCE_OF_STATUS_EFFECT && !bit) {
        p.damage /= 2;
        str[STATUS] += "WEAKENED ";
        bit = true;
    }
    else if (time == 0) {
        p.damage *= 2;
        str[STATUS].replace(str[STATUS].find("WEAKENED ", 0), 9, "");

        time = 2;  // <-- error
        bit = false;
    }
    else if (bit) {
        time--;
    }
}

我在第二个条件中的第time = 2;行收到std :: out_of_range错误。通过主攻击函数的函数指针调用此函数。该错误似乎是随机的,MSVS报告所有变量具有错误发生时应具有的值。

1 个答案:

答案 0 :(得分:0)

该行

str[STATUS].replace(str[STATUS].find("WEAKENED ", 0), 9, "");

只是一场灾难等待发生。让我们先看一下内心的发现。

str[STATUS].find("WEAKENED ", 0)

你在短程序中使用值“WEAKENED”两次,当你经常这样做时你会有拼写错误,因此最好在这里使用一个命名值,这样就不会出错。

constexpr const char *WeakenedStr = "WEAKENED ";

然后使用

str[STATUS].find(WeakenedStr , 0)

其次这可能会失败,如果找不到字符串,则返回'npos'(当前为-1)。所以我们也需要测试一下

auto pos = str[STATUS].find("WEAKENED ", 0);
if (pos != std::string::npos)
  str[STATUS].replace(pos, 9, "");

接下来是'9'这是一个幻数,它也应该是一个命名值

constexpr const char *WeakenedStr = "WEAKENED ";
const int WeakenedStrLen = strlen(WeakenedStr); // strlen is sadly not constexpr.

给予

auto pos = str[STATUS].find("WEAKENED ", 0);
if (pos != std::string::npos)
  str[STATUS].replace(pos, WeakenedStrLen, "");

注意:未经测试的代码会发生错误。