对象在添加到 STL 容器时超出范围

Objects go out of scope when added to STL container

本文关键字:范围 添加 STL 对象      更新时间:2023-10-16

我目前正在将对象添加到容器(Vector),但是一旦方法结束,向量就会再次为空。 这怎么可能?

int getNumber(std::string input, int& index) {
    int i = 0;
    bool hasNegative = false;
    while (true) {
        char c = input[index + i];
        if (c == '-') {
            if (hasNegative) {
                break;
            }
            else {
                hasNegative = true;
            }
        }
        else if (!isdigit(c)) {
            break;
        }
        i++;
    }
    int result = atoi(input.substr(index, i).c_str());
    index += i;
    return result;
}
Expression makeExpression(std::string input, int& index) {
    Function func = getOperator(input[index]);
    Function func1 = getOperator(input[index + 1]);
    if (input[index + 2] != '=') {
        std::cout << "Error!" << std::endl;
    }
    index += 3;
    int equals = getNumber(input, index);
    std::vector<Function> op{ func, func1 };
    return Expression(op, equals);
}
int main(int argc, char* argv[]) {
    std::string input = std::string(argv[argc - 1]);
    std::cout << input << std::endl;
    int index = 0;
    std::vector<Expression> expressions;
    expressions.reserve(6);
    for (int i = 0; i < 6; i++) {
        Expression e = makeExpression(input, index);
        expressions.push_back(e);
        e.evaluate();
        Expression::ResultSet results = e.getAnswers(); // Empty!
        std::cout << i << std::endl;
        for (std::tuple<int, int, int> answer : results) {
            std::cout << std::get<0>(answer) << " " << std::get<1>(answer) << " " << std::get<2>(answer) << std::endl;
        }
    }

表达

class Expression {
public:
    typedef std::function<int(int, int)> Function;
    typedef std::vector<Function> OperatorSet;
    OperatorSet opSet;
    typedef std::tuple<int, int, int> Result;
    typedef std::vector<Result> ResultSet;
    ResultSet resultSet;
    int equals;
    Expression(OperatorSet opSet, int equals) : resultSet(), opSet(opSet), equals(equals) {
    }
    ResultSet getAnswers()const {
        return resultSet;
    }
    void evaluate() {
        Function one = opSet[0];
        Function two = opSet[1];
        // Both + or -
        if (isBasicArithmetic(one) && isBasicArithmetic(two)) {
            FactorSet set = getSumsOfNine(equals, false);
            for (IntPair pair : set) {
                FactorSet set1 = getSumsOfNine(pair.second, true);
                for (IntPair pair1 : set1) {
                    if (pair.first == pair1.first || pair.first == pair1.second) {
                        continue;
                    }
                    resultSet.push_back(Result(pair.first, pair1.first, pair1.second));
                }
            }
        }
        // One
        else if (isBasicArithmetic(one)) {
            FactorSet set = getSumsOfNine(equals, false);
            for (IntPair pair : set) {
                FactorSet set1 = getFactorsOfNine(pair.second, true);
                for (IntPair pair1 : set1) {
                    if (pair.first == pair1.first || pair.first == pair1.second) {
                        continue;
                    }
                    resultSet.push_back(Result(pair.first, pair1.first, pair1.second));
                }
            }
        }
        // Two
        else if (isBasicArithmetic(two)) {
            FactorSet set = getSumsOfNine(equals, false);
            for (IntPair pair : set) {
                FactorSet set1 = getFactorsOfNine(pair.second, true);
                for (IntPair pair1 : set1) {
                    if (pair.first == pair1.first || pair.first == pair1.second) {
                        continue;
                    }
                    resultSet.push_back(Result(pair1.first, pair1.second, pair.first));
                }
            }
        }
        // Both
        else {
            FactorSet set = getFactorsOfNine(equals, false);
            for (IntPair pair : set) {
                if (pair.second > 9 + 8) {
                    continue;
                }
                FactorSet set1 = getFactorsOfNine(pair.second, true);
                for (IntPair pair1 : set1) {
                    if (pair.first == pair1.first || pair.first == pair1.second) {
                        continue;
                    }
                    resultSet.push_back(Result(pair1.first, pair1.second, pair.first));
                }
            }
        }
        std::cout << resultSet.size() << std::endl;
    }
};

并且在方法主体的末尾,resultSet 具有正确的大小,但通过下一个方法调用 resultSet 再次为零。

如果您静态创建对象,然后将它们的引用添加到方法中的向量或任何容器,则当您离开该方法时,它们将从堆栈中弹出并且不会退出。这可能会导致您的问题,如果是,而是使用 new 或 malloc 动态分配您添加到矢量中的对象。

在你的main()中,你有一个循环。在每次迭代中,创建一个新的 Expression 对象,该对象将其 resultSet 成员初始化为空向量。

如果希望 resultSet 累积数据,尽管每次都对不同的对象调用 evaluate(),则可以使 resultSet 成为 Expression 的静态成员。

另一种选择是在main()中声明一个向量,并在每次调用时将getAnswers()的结果附加到其中。