我有一个类测试器,我决定将static声明为Foo类的成员,

class Tester {

public:

    bool test(const Data &d);
};

class Foo {

    static Tester tester;
};


但是,当我从Foo实例调用tester.test(data)时,程序可以正常编译,但在调用后没有响应。当我将Tester :: test设为静态时,

class Tester {

public:

    static bool test(const data &d);
};


然后就可以了。为什么是这样?似乎我应该能够声明一个静态类并使用它的非静态成员,例如,如果我有一个静态向量。我正在使用gcc 4.7进行编译。

最佳答案

我相信您会收到链接器错误(对吗?)。这是因为您没有给出Foo::tester的定义。 (您仅提供其声明。)

Foo.cpp文件中添加以下行:

Tester Foo::tester;


这是Foo::tester的定义,并修复了链接问题。

更新这里是一个完整的示例:

#include <iostream>

class Data {};

class Tester {

public:

    bool test(const Data &) { std::cout << "Yes\n"; return true; }
};

class Foo {

    static Tester tester;

public:

    Foo() {
        Data data;
        tester.test(data);
    }
};

Tester Foo::tester;

int main() {
    Foo f;
}


它编译,链接,运行并输出Yes

更新2在思考了本·沃伊特的评论后。

如果删除Foo::tester的定义,则代码不会链接。如果随后将Tester::test设为静态(如OP所述),则它将再次链接并按预期运行。

经过反思,这实际上是有道理的。如果未定义tester,则无法在其上调用(非静态)方法。但是,如果该方法是静态的,则不需要对象,只需要其类型即可进行调用。当编译器看到调用tester.test(data);时(我猜),它仅考虑tester的类型(由声明提供),然后代码起作用。

09-07 07:26
查看更多