CppUnit:为什么静态局部变量会保留其值?

CppUnit: Why does a static local variable keep its value?

我正在尝试使用 CppUnit 测试一种方法,该方法应仅在第一次调用时执行某些代码。

class CElementParseInputTests: public CppUnit::TestFixture {
private:
    CElement* element;
public:

    void setUp() {
        element = new CElement();
    }

    void tearDown() {
        delete element;
    }

    void test1() {
        unsigned int parsePosition = 0;
        CPPUNIT_ASSERT_EQUAL(false, element->parseInput("fäil", parsePosition));
    }

    void test2() {
        unsigned int parsePosition = 0;
        CPPUNIT_ASSERT_EQUAL(false, element->parseInput("pass", parsePosition));
    }

我要测试的递归方法:

bool CElement::parseInput(const std::string& input, unsigned int& parsePosition) {
    static bool checkedForNonASCII = false;
    if(!checkedForNonASCII) {
        std::cout << "this should be printed once for every test case" << std::endl;
        [...]
        checkedForNonASCII = true;
    }
    [...]
    parseInput(input, parsePosition+1)
    [...]
}

由于对象是为每个测试用例重新创建然后销毁的,所以我希望字符串 "this should be printed once for every test case" 在 运行 测试时会打印两次,但它只打印一次。我错过了什么?

这就是 static local variables 应该做的。

Variables declared at block scope with the specifier static have static storage duration but are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered). On all further calls, the declaration is skipped.

这意味着 checkedForNonASCII 只会在第一次调用时被初始化为 false 一次。对于进一步的调用,初始化被跳过;即 checkedForNonASCII 不会再次初始化为 false

其他答案是怎么说的。但这可能是您真正想要的:

bool CElement::parseInput(const std::string& input, unsigned int& parsePosition)
{
    [...] // your code for validating ascii only characters goes here
    if (hasNonAsciiCharacters) {
       return false;
    }

    return parseInputInteral(input, parsePosition);
}

bool CElement::parseInputInternal(const std::string& input, unsigned int& parsePosition)
{
    [...]
    parseInputInternal(input, parsePosition+1);
    [...]
    return result;
}