and*_*wrk 245 c++ oop syntax static class
如何在C++中创建静态类?我应该可以这样做:
cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
Run Code Online (Sandbox Code Playgroud)
假设我创建了这个BitParser
类.将在哪些BitParser
类定义是什么样子?
OJ.*_*OJ. 258
如果您正在寻找一种将"static"关键字应用于类的方法,例如您可以在C#中使用,那么您将无法使用Managed 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() {}
};
Run Code Online (Sandbox Code Playgroud)
BitParser.cpp
bool BitParser::getBitAt(int buffer, int bitIndex)
{
bool isBitSet = false;
// .. determine if bit is set
return isBitSet;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用此代码以与示例代码相同的方式调用该方法.
希望有所帮助!干杯.
pae*_*bal 238
考虑一下Matt Price的解决方案.
你想要的是,用C++语义表达,将你的函数(因为它是一个函数)放在命名空间中.
C++中没有"静态类".最近的概念是只有静态方法的类.例如:
// header
class MyClass
{
public :
static void myMethod() ;
} ;
// source
void MyClass::myMethod()
{
// etc.
}
Run Code Online (Sandbox Code Playgroud)
但是你必须记住,"静态类"是类似Java的语言(例如C#)中的黑客,它们不能拥有非成员函数,所以他们反而将它们作为静态方法移到类中.
在C++中,您真正想要的是一个非成员函数,您将在命名空间中声明:
// header
namespace MyNamespace
{
void myMethod() ;
}
// source
namespace MyNamespace
{
void myMethod()
{
// etc.
}
}
Run Code Online (Sandbox Code Playgroud)
在C++中,命名空间比"Java静态方法"模式的类更强大,因为:
结论:不要在C++中复制/粘贴Java/C#的模式.在Java/C#中,模式是必需的.但在C++中,风格很糟糕.
有一个论点支持静态方法,因为有时需要使用静态私有成员变量.
我有点不同意,如下图所示:
// HPP
class Foo
{
public :
void barA() ;
private :
void barB() ;
static std::string myGlobal ;
} ;
Run Code Online (Sandbox Code Playgroud)
首先,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 !!!
}
Run Code Online (Sandbox Code Playgroud)
乍一看,自由功能barC无法访问Foo :: myGlobal这一事实从封装角度来看似乎是一件好事...这很酷,因为有人看着HPP将无法(除非采取破坏行为)访问富:: myGlobal.
但是如果仔细观察,你会发现这是一个巨大的错误:不仅你的私有变量仍然必须在HPP中声明(因此,尽管是私有的,但是对全世界都是可见的),但你必须声明在同一HPP所有(如在所有)功能,将被授权访问它!
因此,使用私人静态成员就像在裸体外面散步一样,你的爱人纹身在你的皮肤上:没有人有权触摸,但每个人都可以偷看.奖金:每个人都可以拥有被授权与你的私人玩耍的人的名字.
private
确实...... :-D
匿名命名空间的优势在于私有化私有.
首先是HPP标头
// HPP
namespace Foo
{
void barA() ;
}
Run Code Online (Sandbox Code Playgroud)
只是为了确定你说过:barB和myGlobal都没有无用的声明.这意味着没有人阅读标题知道barA背后隐藏着什么.
然后,CPP:
// 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 !!!
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,就像所谓的"静态类"声明一样,fooA和fooB仍然可以访问myGlobal.但没有人可以.这个CPP之外没有人知道fooB和myGlobal甚至存在!
与在裸体上行走的"静态类"不同,她的皮肤上的地址簿纹身上的"匿名"命名空间完全穿着,这似乎是更好的封装AFAIK.
除非你的代码的用户是破坏者(我会让你,作为练习,找到如何使用脏行为 - 未定义的黑客来访问公共类的私有部分......),即使它private
是什么private
,private
在标题中声明的类的部分中可见.
但是,如果你需要添加另一个"私有函数"来访问私有成员,你仍然必须通过修改标题向全世界声明它,就我而言这是一个悖论:如果我改变了实现我的代码(CPP部分),然后界面(HPP部分)不应该改变.引用列奥尼达斯:" 这是封锁! "
什么时候类静态方法实际上比具有非成员函数的命名空间更好?
当您需要将功能组合在一起并将该组提供给模板时:
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 !!!
Run Code Online (Sandbox Code Playgroud)
因为,如果类可以是模板参数,则命名空间不能.
Mat*_*ice 62
您还可以在命名空间中创建自由函数:
在BitParser.h中
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex);
}
Run Code Online (Sandbox Code Playgroud)
在BitParser.cpp中
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex)
{
//get the bit :)
}
}
Run Code Online (Sandbox Code Playgroud)
通常,这将是编写代码的首选方法.当不需要对象时不要使用类.
Ori*_*rds 12
如果您正在寻找一种将"static"关键字应用于类的方法,例如您可以在C#中使用
静态类只是编译器手持您并阻止您编写任何实例方法/变量.
如果你只是编写一个没有任何实例方法/变量的普通类,那就是同样的事情,这就是你在C++中所做的
Phi*_*lds 11
在C++中,您希望创建类的静态函数(而不是静态类).
class BitParser {
public:
...
static ... getBitAt(...) {
}
};
Run Code Online (Sandbox Code Playgroud)
然后,您应该能够使用BitParser :: getBitAt()调用该函数,而无需实例化我认为是所需结果的对象.
Cir*_*四事件 10
我能写点什么static class
吗?
不,根据C++ 11 N3337标准草案附件C 7.1.1:
更改:在C++中,静态或外部说明符只能应用于对象或函数的名称.在C++中使用带有类型声明的这些说明符是非法的.在C中,在类型声明上使用时会忽略这些说明符.例:
Run Code Online (Sandbox Code Playgroud)static struct S { // valid C, invalid in C++ int i; };
基本原理:与类型关联时,存储类说明符没有任何意义.在C++中,可以使用静态存储类说明符声明类成员.允许类型声明上的存储类说明符可能会使代码对用户造成混淆.
而且struct
,class
也是一种类型声明.
通过走附录A中的语法树可以推导出同样的结果.
有趣的是,它static struct
在C 中是合法的,但没有效果:为什么以及何时在C编程中使用静态结构?
As it has been noted here, a better way of achieving this in C++ might be using namespaces. But since no one has mentioned the final
keyword here, I'm posting what a direct equivalent of static class
from C# would look like in C++11 or later:
class BitParser final
{
public:
BitParser() = delete;
static bool GetBitAt(int buffer, int pos);
};
bool BitParser::GetBitAt(int buffer, int pos)
{
// your code
}
Run Code Online (Sandbox Code Playgroud)