命名空间和私有静态类成员

时间:2012-05-20 13:54:59

标签: c++ object static namespaces initialization

为什么这样做:

#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没有用? (仍然是我原来问题的一部分。)所以,到目前为止,我们已经半答案了。

我想知道 为什么 这不起作用所以我不会再次进入这个耙子了。

2 个答案:

答案 0 :(得分:3)

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

修复它?首先在int main();之前(和之外)声明namespace test,然后在friend int ::main()声明它在全局命名空间中。

有关详细信息,请参阅this question

答案 1 :(得分:1)

好吧,虽然我永远不会建议你像你在问题中那样做,但这里是如何使你的代码工作&#34;按照&#34; :

#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中使用一个函数)对于可读性和可理解性来说要好得多。