题
你怎么创建一个静态的类在C++?我应该能做些什么,如:
cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
假设我创造的 BitParser
类。会是什么样的 BitParser
类定义看起来像什么?
解决方案
如果你是在寻找一种方法的应用"静态"的关键词一类的,像你可以在C#例如,那么你就不能不使用管理C++。
但看你的样本,你只需要创建一个公共静态的方法在您的BitParser对象。像这样:
BitParser.h
class BitParser
{
public:
static bool getBitAt(int buffer, int bitIndex);
// ...lots of great stuff
private:
// Disallow creating an instance of this object
BitParser() {}
};
BitParser.cpp
bool BitParser::getBitAt(int buffer, int bitIndex)
{
bool isBitSet = false;
// .. determine if bit is set
return isBitSet;
}
你可以使用这个代码拨打的方法以同样的方式作为你的代码。
希望这可以帮助!欢呼声。
其他提示
考虑 马特的价格氏液.
- C++、"静态级"没有意义。最近的事情是一类只有静态的方法和成员。
- 使用静态的方法将只限。
你想要什么,表示C++语义,把你的功能(对于它 是 一个功能)在名称空间。
编辑2011-11-11
有没有"静态班"C++。最近的概念将是一类只有静态的方法。例如:
// header
class MyClass
{
public :
static void myMethod() ;
} ;
// source
void MyClass::myMethod()
{
// etc.
}
但是你必须记住,"静态的课程"是黑客在Java-喜欢那种语言(例如C#),都无法有非成员的功能,使他们有,而不是将他们内部的类作为静态的方法。
C++,你真正想要的是一个非成员的功能,你将宣布在一个名字空间:
// header
namespace MyNamespace
{
void myMethod() ;
}
// source
namespace MyNamespace
{
void myMethod()
{
// etc.
}
}
为什么?
在C++、空间更为强大的比类为"Java静态的方法"的模式,因为:
- 静态的方法有接到类私人的符号
- 私人静态的方法仍然可见(如果无法访问)为每个人,这违反略的封装
- 静态的方法不能前宣布
- 静态的方法不能重载的类的用户,而无需修改的图书馆头
- 没有什么可以通过一个静态的方法,该方法不可能做更好的比(可能的朋友)非成员的功能相同的名字空间
- 名字空间有自己的语义(他们可以合并,它们可以匿名,等等。)
- 等等。
结论:不要复制、粘贴Java/C#'s模式C++。在Java/C#模式是强制性的。但在C++,它是坏的风格。
编辑2010-06-10
有一个论点支持以静态的方法,因为有时候,一个需要使用一个静态的私营部件的变量。
我不同意,如下所示:
"静态的私人成员"的解决方案
// HPP
class Foo
{
public :
void barA() ;
private :
void barB() ;
static std::string myGlobal ;
} ;
首先,myGlobal被称为myGlobal,因为它仍然是一个全球私变量。看看CPP源将澄清的是:
// 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似乎是一个良好的事情从一个封装的观点...这很酷,因为有人看的HPP不可能的(除非诉诸破坏)访问Foo::myGlobal.
但如果你看它密切合作,你会发现这是一个巨大的错误:不仅是你的私人变量仍然必须宣布在HPP(和因此,看到所有的世界,尽管被私人的),但是必须宣布在同一HPP所有的(正如在所有)的功能,将经授权的访问它!
所以 使用一个私人的静态部件是像走在外面的裸体清单的你的爱人纹在你的皮肤:没有一个人被授权接触,但每个人都能看看.和奖金:每个人都可以拥有姓名的那些授权发挥你的厕.
private
事实上...:-D
"匿名命名空间"的解决方案
匿名命名空间会有的优点私人的事情真的是私人的。
第一,HPP头
// HPP
namespace Foo
{
void barA() ;
}
只是要确定你说:没有没用的宣言》的倒钩,也不myGlobal.这意味着,没有人阅读的头知道什么是隐藏在背后barA。
然后,加拿大养恤金计划:
// CPP
namespace Foo
{
namespace
{
std::string myGlobal ;
void Foo::barB()
{
// I can access Foo::myGlobal
}
}
void barA()
{
// I can access myGlobal, too
}
}
void barC()
{
// I STILL CAN'T access myGlobal !!!
}
正如你可以看到,如所谓的"静态的类"宣言》,fooA和fooB仍然能够访问myGlobal.但没有人可以。并没有其他人之外这CPP知道fooB和myGlobal甚至存在!
不同的是"静态级的"上行走的裸体与她的地址本书纹在了她的皮肤的"匿名"名称空间是穿着衣服, ,这似乎相当好的封据我所知.
它真的重要吗?
除非用户的代码被破坏者(我会让你作为一个练习,如何找到一个可以进入私人部分的公共类使用的一种肮脏行为的不确定哈克...),什么 private
是 private
, 即使这是可见的 private
第一类声明的标题。
仍然,如果你需要添加另一个"私人"功能进入私人成员,你仍然必须宣布它向全世界通过修改标题,这是一种矛盾现象作为我关心的: 如果我改变的执行情况,我的代码(加拿大养恤金计划的一部分),然后接口(HPP部分)不应改变。 引用Leonidas:"这是封装!"
编辑2014-09-20
当类的静态的方法是比实际上更好的名称空间与非成员职能?
当你需要组合在一起的功能和饲料,小组到一个模板:
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<alpha> ga ; // compilation error
Gamma<Beta> gb ; // ok
gb.foobar() ; // ok !!!
因为,如果一类可能是一个模板参数、名称空间。
你还可以创建一个免费的功能在一个名字空间:
在BitParser.h
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex);
}
在BitParser.cpp
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex)
{
//get the bit :)
}
}
一般来说,这将是首选方式编写代码。当没有必要的对象不要使用的一类。
如果你是在寻找一种方法的应用"静态"的关键词一类的,像你可以在C#例如
静类是只编译器方面保持你和阻止你写作的任何实例的方法/变量。
如果你只是写一个正常上课没有任何实例的方法/变量的,它是同样的事情,这是你会怎么做C++
C++你想创建一个静态功能的一级(而不是一个静态的类)。
class BitParser {
public:
...
static ... getBitAt(...) {
}
};
你应该然后可以打电话的功能,使用BitParser::getBitAt()没有实例,一个对象我猜是所期望的结果。
我可以写一些东西喜欢 static class
?
没有, ,根据该 C++11N3337标准草案 附件C7.1.1:
改变:在C++、静态或外部说明符只能适用于名称的目的或功能。使用这些说明具有类型的声明是非法的,在C++。在C中,这些说明符被忽略的时候使用 在类型声明。例如:
static struct S { // valid C, invalid in C++ int i; };
理由:储存的类符没有任何意义相关联的类型。C++、类 成员可以声明,与静态存储类说明符。允许储存的类符的类型 声明可能会导致混乱的代码用户使用。
和喜欢 struct
, class
也是一种宣言》。
同样可以推导出走的语法中的树附件A。
有趣的是,要注意 static struct
是合法的,在C,但是没有效果: 为什么当使用静态结构中的C编程?
你可以有一个静态的类在C++,如前所述,一个静态的类是一个不具有任何目的,它实例。C++,这可以通过声明构造/析构作为私人的。最终结果是一样的。
在管理C++、静态级语法是:-
public ref class BitParser abstract sealed
{
public:
static bool GetBitAt(...)
{
...
}
}
...迟到总比不到好...
这是类似的C#'s的方式这样做C++
C#文件。cs你可以拥有私人var内的公共职能。当在另一个文件可以使用它通过调用空间的功能:
MyNamespace.Function(blah);
这里是如何进口的相同的用C++:
SharedModule.h
class TheDataToBeHidden
{
public:
static int _var1;
static int _var2;
};
namespace SharedData
{
void SetError(const char *Message, const char *Title);
void DisplayError(void);
}
SharedModule.cpp
//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
}
}
OtherFile.h
#include "SharedModule.h"
OtherFile.cpp
//Call the functions using the hidden variables
SharedData::SetError("Hello", "World");
SharedData::DisplayError();
不同于其他管理编程语言,"静态级"没有意义在C++。你可以使用的静态部件的功能。
因为已经在这里指出,一种更好的方式实现这C++可能会使用的名称空间。但是,因为没有人已经提到过的 final
关键词这里,我发帖什么的直接等同的 static class
从C#看起来像是在C++11或后来:
class BitParser final
{
public:
BitParser() = delete;
static bool GetBitAt(int buffer, int pos);
};
bool BitParser::GetBitAt(int buffer, int pos)
{
// your code
}
一种情况下名字空间的可能不那么有用于实现"静态的课程"是当使用这些类实现了组成超过继承。名字空间,不能成为朋友的类,因此无法访问的私人会员一类。
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;
}
};