2

为什么会这样:

#include "iostream"

class Something {
private:
    static int s_nIDGenerator;
    int m_nID;
    friend int main();
public:
     Something() { m_nID = s_nIDGenerator++; }
     int GetID() const { return m_nID; }
};

int Something::s_nIDGenerator;

int main() {
    Something::s_nIDGenerator = 1;

    Something cFirst;
    Something cSecond;
    Something cThird;

    using namespace std;
    cout << cFirst.GetID() << endl;
    cout << cSecond.GetID() << endl;
    cout << cThird.GetID() << endl;
    return 0;
}

它打印:

1
2
3

这失败了:

#include "iostream"

namespace test {   
    class Something {
    private:
            static int s_nIDGenerator;
            int m_nID;
            friend int main();
    public:
            Something() { m_nID = s_nIDGenerator++; }
            int GetID() const { return m_nID; }
    };
};

int test::Something::s_nIDGenerator;

int main() {
    using namespace test;
    Something::s_nIDGenerator = 1;
    // or test::Something::s_nIDGenerator = 1;  same effect if not using using.

    Something cFirst;
    Something cSecond;
    Something cThird;

    using namespace std;
    cout << cFirst.GetID() << endl;
    cout << cSecond.GetID() << endl;
    cout << cThird.GetID() << endl;
    return 0;
}

编译器错误消息为:

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\tuttest1.o ..\src\tuttest1.cpp
..\src\tuttest1.cpp: In function 'int main()':
..\src\tuttest1.cpp:23:5: error: 'int test::Something::s_nIDGenerator' is private
..\src\tuttest1.cpp:27:13: error: within this context
Build error occurred, build is stopped
Time consumed: 161  ms. 

如何让第二个示例使用命名空间测试工作?

对象周围的命名空间声明如何/为什么阻止访问静态成员表单?


根据我对@zmo 的评论,这是我根据他的线索要做的工作:

(评论没有空间或格式,我不得不编辑,因为我无法设置这个答案......(无论需要什么。)

#include "iostream"

namespace test {
    class Something {
    private:
        static int s_nIDGenerator;
        int m_nID;
        friend void load(int);
    public:
        Something() { m_nID = s_nIDGenerator++; }
        int GetID() const { return m_nID; }
    };

    int Something::s_nIDGenerator;

    void load (int value) {
       Something::s_nIDGenerator = value;
    } 

};

int main() {
    using namespace test;
    load (1);

    Something cFirst;
    Something cSecond;
    Something cThird;

    using namespace std;
    cout << cFirst.GetID() << endl;
    cout << cSecond.GetID() << endl;
    cout << cThird.GetID() << endl;
    return 0;
}

对于“静态成员在一个类中而命名空间不起作用是怎么回事?”我仍然有点松散。这是怎么回事?为什么没有test::Something::s_nIDGenerator工作?(仍然是我最初问题的一部分。)所以,到目前为止,我们只回答了一半。

我想知道为什么这不起作用,所以我不再走进这个耙子。

4

2 回答 2

3

可能是因为您的friend int main()声明是声明命名空间也有一个自由main()函数,而真正的main()函数不在命名空间中。

要解决这个问题?首先声明int main();before (and outside) namespace test,然后friend int ::main()表明它在全局命名空间中。

有关更多详细信息,请参阅此问题

于 2012-05-20T14:00:43.350 回答
1

好吧,尽管我永远不会建议您像您在问题中所做的那样做,但这里是如何使您的代码“按原样”工作的方法:

#include <iostream>

int main(); // declare main beforehands so it can be seen by Something

namespace test {   
    class Something {
    private:
            static int s_nIDGenerator;
            int m_nID;
            friend int ::main(); // take the main from global namespace
    public:
            Something() { m_nID = s_nIDGenerator++; }
            int GetID() const { return m_nID; }
    };
};

int test::Something::s_nIDGenerator;

int main() {
    using namespace test;
    Something::s_nIDGenerator = 1; // tada that works

    Something cFirst;
    Something cSecond;
    Something cThird;

    using namespace std;
    cout << cFirst.GetID() << endl;
    cout << cSecond.GetID() << endl;
    cout << cThird.GetID() << endl;
    return 0;
}

但这是友元函数的错误用例。我建议的似乎对您有用的解决方案(在您的类 Something 中使用函数)在可读性和可理解性方面要好得多。

于 2012-05-20T14:41:13.697 回答