Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 命名空间和私有静态类成员_C++_Object_Static_Namespaces_Initialization - Fatal编程技术网

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

C++ 命名空间和私有静态类成员,c++,object,static,namespaces,initialization,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_nIDGen

为什么这样做有效:

#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;
}
而这个失败:

#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;
}
如何使用名称空间测试使第二个示例工作

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


根据我对@zmo的评论,以下是我根据他的线索得出的结论:

(注释没有足够的空间或格式,我不得不编辑,因为我无法将其设置为答案……(不管需要什么。)

#包括“iostream”
名称空间测试{
分类{
私人:
静态整数序列发生器;
国际货币基金组织;
虚荷载(int);
公众:
Something(){m_nID=s_nIDGenerator++}
int GetID()常量{return m_nID;}
};
int Something::s_nIDGenerator;
无效荷载(int值){
Something::s_nIDGenerator=值;
} 
};
int main(){
使用名称空间测试;
载荷(1);
第一件事;
第二件事;
第三种东西;
使用名称空间std;

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

要修复它?首先在
名称空间测试之前(和外部)
声明
int main();
,然后
friend int::main()
以指示它在全局名称空间中


有关更多详细信息,请参阅。

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

要修复它?首先在
名称空间测试之前(和外部)
声明
int main();
,然后
friend int::main()
以指示它在全局名称空间中


有关更多详细信息,请参见。

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

#包括
int main();//在指针之前声明main,以便被某些对象看到
命名空间测试{
分类{
私人:
静态整数序列发生器;
国际货币基金组织;
friend int::main();//从全局命名空间获取main
公众:
Something(){m_nID=s_nIDGenerator++}
int GetID()常量{return m_nID;}
};
};
int-test::Something::s_-nIDGenerator;
int main(){
使用名称空间测试;
Something::s_nIDGenerator=1;//塔达可以正常工作
第一件事;
第二件事;
第三种东西;
使用名称空间std;

cout好吧,虽然我永远不会建议您像在问题中那样做,但下面是如何使代码“按原样”工作:

#包括
int main();//在指针之前声明main,以便被某些对象看到
命名空间测试{
分类{
私人:
静态整数序列发生器;
国际货币基金组织;
friend int::main();//从全局命名空间获取main
公众:
Something(){m_nID=s_nIDGenerator++}
int GetID()常量{return m_nID;}
};
};
int-test::Something::s_-nIDGenerator;
int main(){
使用名称空间测试;
Something::s_nIDGenerator=1;//塔达可以正常工作
第一件事;
第二件事;
第三种东西;
使用名称空间std;

尽管它可能会起作用,但让::main()成为类的朋友并不是一个好主意。您最好在类中的函数中编写::main()朋友代码,并从::main()调用它.2美分。@zmo就是这个,谢谢!你给了我我需要的线索。把一个函数放在可以访问静态变量的类中。我对此感到厌倦,它在我的测试示例和我的实际项目中都起了作用。(仍然没有给我一个“为什么”…只是一个“什么”关于如何解决这个问题。我会把它作为一个答案贴出来,但如果有人能解释的话,我会贴上“接受”的标签。(很明显,我的学习材料没有足够涵盖事情的“原因”)。我猜你看不到它了……:(糟糕!无法提交您的答案,因为:信誉低于100的用户在提问后8小时内无法回答自己的问题。您可以在7小时内自行回答。在此之前,请使用评论,或编辑您的问题。这:7.3.1.2名称空间成员定义第3段在名称空间中首先声明的每个名称都是该名称空间的成员。如果非本地类中的友元声明首先声明一个类或函数(这意味着该类或函数的名称是非限定的)friend类或函数是最内层封闭命名空间的成员。原因就在这篇文章中。“仔细看,这就是为什么它将其标记为private。这就是我的原因。这不是因为名称无法访问它,而是因为试图使用它的内容没有在适当的范围内声明。尽管它可能会起作用,但让::main()成为类的朋友不是一个好主意。你最好做一下::main()在类中的函数中编写友元代码,并从::main()调用它。我的2美分。@zmo就是这样,谢谢!你给了我所需要的线索。将一个函数放在可以访问静态变量的类中。我对此感到厌倦,它在我的测试示例和实际项目中都起作用。(仍然没有给我答案。)“为什么”…只是一个关于如何修复它的“什么”。我会把它作为一个答案发布,但如果有人能解释这一点,我会标记为“接受”。(显然,我的学习材料没有足够涵盖事情的“为什么”。)我想你不会看到它的哎呀!您的答案无法提交,因为:声誉低于100的用户在提问后8小时内无法回答自己的问题。您可以在7小时内自行回答。在此之前,请使用注释,或编辑您的问题。”此:“7.3.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. 
#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;
}
#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;
}