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