简体   繁体   English

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

[英]namespace and private static class members

Why does this work: 为什么这样做:

#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;
}

it prints: 它打印:

1
2
3

And this fail: 这失败了:

#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;
}

With the compiler error message of: 随着以下编译器错误消息:

**** 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. 

How do I get the 2nd example to work using the namespace test? 如何使用名称空间测试使第二个示例工作?

How/Why is the namespace declaration around the object preventing the static member form being accessible? 为什么/为什么围绕对象的名称空间声明阻止了静态成员形式的访问?


Per my comment to @zmo, here is what I got to work based on his clue: 根据我对@zmo的评论,这是根据他的提示我要做的工作:

(comment doesn't have the space or formatting for this, and I had to edit because I couldn't set this an answer.... (what ever it takes.) (注释没有空格或格式,并且我必须进行编辑,因为我无法将其设置为答案。...(需要什么。)

#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;
}

I am still a little loose as to the "what's up with static members being in a class and a namespace not working?" 对于“静态成员在类中并且命名空间不起作用的情况如何”,我还是有些松懈。 What's up with this? 这是怎么回事? Why didn't test::Something::s_nIDGenerator work? 为什么不test::Something::s_nIDGenerator起作用? (still a part of my original question.) So, we are half-answered, so far. (仍然是我最初的问题的一部分。)因此,到目前为止,我们的回答是一半。

I want to know why this didn't work so I don't walk into this rake again. 我想知道为什么这行不通,所以我再也不会陷入这种困境。

Probably because your friend int main() declaration is declaring that the namespace also has a free main() function, while the real main() function is not in the namespace. 可能是因为您的friend int main()声明正在声明名称空间也具有免费的main()函数,而真正的main()函数不在名称空间中。

To fix it? 要解决这个问题? First declare int main(); 首先声明int main(); before (and outside) namespace test , then friend int ::main() to indicate it's in the global namespace. namespace test之前(和外部),然后与friend int ::main()进行交互,以表明它位于全局名称空间中。

For more details, see this question . 有关更多详细信息,请参见此问题

well, though I will never recommand you to do like you did in your question, here is how to make your code work "as is" : 好吧,尽管我永远不会建议您像您在问题中所做的那样做,但这是如何使您的代码“按原样”工作:

#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;
}

but here is a wrong use case of a friend function. 但这是朋友功能的错误用例。 The solution that seemed to work for you that I suggested (use a function inside your class Something) is far better for readability and understandability. 我建议的对您似乎有效的解决方案(在类Something中使用函数)对于可读性和可理解性而言要好得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM