如何在C++中创建静态类?我应该可以做一些像:
1
| cout <<"bit 5 is" << BitParser::getBitAt(buffer, 5) << endl; |
假设我创建了BitParser类。BitParser类定义是什么样的?
如果你正在寻找一种将"静态"关键字应用到类中的方法,比如你可以在C语言中使用,那么你就不可能不使用托管C++。
但从示例的外观来看,您只需要在BitParser对象上创建一个公共静态方法。像这样:
BitParser
1 2 3 4 5 6 7 8 9 10 11
| class BitParser
{
public:
static bool getBitAt(int buffer, int bitIndex);
// ...lots of great stuff
private:
// Disallow creating an instance of this object
BitParser() {}
}; |
位PARSPR.CPP
1 2 3 4 5 6
| bool BitParser::getBitAt(int buffer, int bitIndex)
{
bool isBitSet = false;
// .. determine if bit is set
return isBitSet;
} |
可以使用此代码以与示例代码相同的方式调用方法。
希望有帮助!干杯。
马特考虑价格的解决方案。 </P >好。
在C++中,一个"静态类"已经没有意义。在最近的东西是一类以只读静态方法和成员。
使用静态方法只会限制你。
什么是你想要的冰,表示在C++的语义来把你的功能(它是一个功能)在一个命名空间。 </P >好。 编辑:2011年11月11日
有没有"静态冰级"的C + +。在最近的概念,会用一只类的静态方法。例如: </P >好。
1 2 3 4 5 6 7 8 9 10 11 12
| // header
class MyClass
{
public :
static void myMethod() ;
} ;
// source
void MyClass::myMethod()
{
// etc.
} |
但你必须记得,那是"静态类"是黑客的Java类的面颊部语言(例如C #)那是不能要有非成员函数,所以他们的行动,而不是对他们有作为静态内部类的方法。 </P >好。
在C++中,什么是你真的想要的是一个非成员函数,你将在一个命名空间:DECLARE </P >好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| // header
namespace MyNamespace
{
void myMethod() ;
}
// source
namespace MyNamespace
{
void myMethod()
{
// etc.
}
} |
这是为什么呢?
C++的命名空间,比冰更强大的"Java类的静态方法"的模式,因为: </P >好。
- 静态方法的类,有私人访问的符号
- 私人的静态方法是静止不动的(如果inaccessible)可见到每一个人,这breaches somewhat《encapsulation
- 静态方法不能申报要求的大前锋。
- 静态方法不能求overloaded皇家级的用户没有modifying头的图书馆
- 有什么我可以做的冰做的由一个静态方法,能做的更好的比A(可能的朋友)功能的非成员国一样,命名空间
- 命名空间有其自身的语义(他们可以做结合,他们可以要求匿名,等。)
- 等。
结论:不要拷贝/粘贴/ C,Java #’s型C + +。在Java / C #,强制型的冰。但在C + +,它的冰浴的风格。 </P >好。 编辑2010年06月10
有一个说法是把你的静态方法,因为有时,需要使用一对一私人的静态成员变量。 </P >好。
在disagree somewhat节目,为下面的: </P >好。 "静态的私人成员"。
1 2 3 4 5 6 7 8 9 10
| // HPP
class Foo
{
public :
void barA() ;
private :
void barB() ;
static std::string myGlobal ;
} ; |
第一,myglobal冰被称为myglobal因为这仍然是一个全球性的私人活动。A看《clarify CPP源会是: </P >好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // CPP
std::string Foo::myGlobal ; // You MUST declare it in a CPP
void Foo::barA()
{
// I can access Foo::myGlobal
}
void Foo::barB()
{
// I can access Foo::myGlobal, too
}
void barC()
{
// I CAN'T access Foo::myGlobal !!!
} |
在一系列的事实,无功能的BARC不能访问foo myglobal表明:一个好的事情从一encapsulation观点…………………这很酷,因为有人在看着HPP不会问A(除非resorting到接入到破坏):myglobal foo。 </P >好。
但如果你看它closely,你会发现,它是一个colossal错误:不只是你的私人的变动要求必须申报的HPP(",可见到全世界的存在,尽管存在私人),但你必须在同一个DECLARE HPP所有(As,把所有的功能是将)授权的访问信息。!!!!!!!!!!!!!! </P >好。
SO利用私人静态成员的冰状的在外的诞生与发展战略tattooed你的恋人对你的皮肤:没有一个授权的冰,冰的触摸,但每一个人能对PEEK实习生。和奖励:每一个人能有个"授权"的名字即插即用和你的厕所。 </P >好。
private的妈妈…… :D </P >好。 匿名名称空间溶液
匿名名称将具有做私人事情的优势。
okay.
First,the HPP header
okay.
1 2 3 4 5 6
| // HPP
namespace Foo
{
void barA() ;
} |
只要你确定你还活着:巴尔博或神话全球的宣言没有用处。这意味着没有人阅读主人知道巴拉背后隐藏着什么
okay.
Then,the CPP:
okay.ZZU1
正如你所看到的那样,所谓的"静态类"宣言、食品和食品仍然可以进入神话。但没有人可以。没有人会知道食物和神话甚至存在!
okay.
不如"静态类"在脖子上随身携带地址簿在她的皮肤上纹上"匿名"的名称空间完全封闭,看上去更容易封闭。
okay.这是真的吗?
Unless the users of your code are saboteurs(I'll let you,a s an exercise,find how one can access to the private part of a public class using a dirty behaviour-undefined hack…),what's privatei s edoc1〔0〕,even if it's visible in the edoc1〔0〕Class
okay.
但是,如果你需要增加一个"私人功能",并能进入私人成员,那么你必须通过改变头部向全世界宣布,这是一个矛盾,正如我所关心的那样:如果我改变我的代码(CPP部分),那么界面(HPP部分)就不应改变。Quoting Leonidas:"这是封装!"
okay.2014-09-20版
当静态类别的方法实际优于非成员函数的名称空间时?
okay.
When you need to group together functions and feed that group to a template:
okay.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| namespace alpha
{
void foo() ;
void bar() ;
}
struct Beta
{
static void foo() ;
static void bar() ;
};
template <typename T>
struct Gamma
{
void foobar()
{
T::foo() ;
T::bar() ;
}
};
Gamma ga ; // compilation error
Gamma<Beta> gb ; // ok
gb.foobar() ; // ok !!! |
因为,如果一个类别可以是一个模板参数,一个名称空间不能。
okay.好吧
还可以在命名空间中创建自由函数:
在BitParser
1 2 3 4
| namespace BitParser
{
bool getBitAt(int buffer, int bitIndex);
} |
在bitparser.cpp中
1 2 3 4 5 6 7
| namespace BitParser
{
bool getBitAt(int buffer, int bitIndex)
{
//get the bit :)
}
} |
一般来说,这是编写代码的首选方法。当不需要对象时,不要使用类。
If you're looking for a way of applying the"static" keyword to a class, like you can in C# for example
静态类只是编译器的一只手,握着你的手,阻止你编写任何实例方法/变量。
如果你只写一个普通类,没有任何实例方法/变量,那是一样的,这就是你在C++中所做的。
在C++中,你要创建一个类的静态函数(不是静态类)。
1 2 3 4 5 6
| class BitParser {
public:
...
static ... getBitAt(...) {
}
}; |
然后,您应该能够使用bitparser::getbitat()调用函数,而无需实例化我认为是所需结果的对象。
我能写点像static class这样的东西吗?
不,根据C++ 11 N337标准草案附录C7.1.1:
Change: In C ++, the static or extern specifiers can only be applied to names of objects or functions.
Using these specifiers with type declarations is illegal in C ++. In C, these specifiers are ignored when used
on type declarations. Example:
1 2 3
| static struct S { // valid C, invalid in C++
int i;
}; |
Rationale: Storage class specifiers don’t have any meaning when associated with a type. In C ++, class
members can be declared with the static storage class specifier. Allowing storage class specifiers on type
declarations could render the code confusing for users.
和struct一样,class也是一种类型声明。
通过浏览附录A中的语法树,可以得出相同的结论。
有趣的是,static struct在C语言中是合法的,但没有效果:为什么以及何时在C语言编程中使用静态结构?
你可以在C++中拥有一个静态类,正如前面提到的,静态类是一个没有任何实例化的对象的类。在C++中,可以通过将构造函数/析构函数声明为私有来获得。最终结果相同。
在托管C++中,静态类语法是:
1 2 3 4 5 6 7 8
| public ref class BitParser abstract sealed
{
public:
static bool GetBitAt(...)
{
...
}
} |
…迟做总比不做好…
与其他托管编程语言不同,"静态类"在C++中没有任何意义。您可以使用静态成员函数。
这类似于C++在C++中的实现方式。
在c file.cs中,在公共函数中可以有私有var。当在另一个文件中时,您可以通过调用具有以下函数的命名空间来使用它:
1
| MyNamespace.Function(blah); |
下面是如何在C++中实现同样的功能:
SharedModule
1 2 3 4 5 6 7 8 9 10 11 12
| class TheDataToBeHidden
{
public:
static int _var1;
static int _var2;
};
namespace SharedData
{
void SetError(const char *Message, const char *Title);
void DisplayError(void);
} |
共享模块.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| //Init the data (Link error if not done)
int TheDataToBeHidden::_var1 = 0;
int TheDataToBeHidden::_var2 = 0;
//Implement the namespace
namespace SharedData
{
void SetError(const char *Message, const char *Title)
{
//blah using TheDataToBeHidden::_var1, etc
}
void DisplayError(void)
{
//blah
}
} |
其他文件
1
| #include"SharedModule.h" |
其他文件
1 2 3
| //Call the functions using the hidden variables
SharedData::SetError("Hello","World");
SharedData::DisplayError(); |
正如这里已经注意到的,在C++中实现这一点的一个更好的方法可能是使用命名空间。但是由于这里没有人提到EDCOX1的4个关键字,所以我发布了一个直接等价于EcOX1的0个词,从C中看,在C++ 11或更后面是:
1 2 3 4 5 6 7 8 9 10 11 12
| class BitParser final
{
public:
BitParser() = delete;
static bool GetBitAt(int buffer, int pos);
};
bool BitParser::GetBitAt(int buffer, int pos)
{
// your code
} |
当使用这些类实现继承上的组合时,名称空间对于实现"静态类"可能不太有用。命名空间不能是类的朋友,因此不能访问类的私有成员。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Class {
public:
void foo() { Static::bar(*this); }
private:
int member{0};
friend class Static;
};
class Static {
public:
template <typename T>
static void bar(T& t) {
t.member = 1;
}
}; |