cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
假设我创建了一个名为
BitParser
的类。那么BitParser
类的定义会是什么样子?cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
BitParser
的类。那么BitParser
类的定义会是什么样子?static
关键字,那么除非使用Managed C++,否则你将无法实现。BitParser
对象上创建一个公共的静态方法。就像这样:
BitParser.h
class BitParser
{
public:
static bool getBitAt(int buffer, int bitIndex);
// ...
// Disallow creating an instance of this object
// (Making all constructors private also works but is not ideal and does not
// convey your intent as well)
BitParser() = delete;
};
BitParser.cpp
bool BitParser::getBitAt(int buffer, int bitIndex)
{
bool isBitSet = false;
// .. determine if bit is set
return isBitSet;
}
private: BitParser() {}
这将防止任何人创建实例。 - Danvilfinal
关键字(从C++11开始)将该类标记为密封类,以防止其他类继承。 - JämesBitParser() = delete;
来明确表达移除构造函数的意图(而不仅仅将其隐藏为 private
)。 - phoenix考虑 Matt Price的解决方案。
你想要的是,在C++语义中,将你的函数(因为它是一个函数)放入命名空间中。
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.
}
}
// 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 !!!
}
// HPP
namespace Foo
{
void 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 !!!
}
在什么情况下,类的静态方法比非成员函数的命名空间更好?
当您需要将函数分组并将该组提供给模板时。
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 !!!
#define private public
... ^_^ ... - paercebalutilities
命名空间中。这样,该函数可以进行单元测试,仍然没有特殊访问私有成员的权限(因为它们在函数调用时作为参数给出)... - paercebal您也可以在命名空间中创建一个免费函数:
在BitParser.h文件中:
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex);
}
在 BitParser.cpp 文件中
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex)
{
//get the bit :)
}
}
一般情况下,这将是编写代码的首选方式。当没有必要使用对象时,请不要使用类。
我能写类似于static class
这样的语法吗?
不行,根据C++11 N3337标准草案附录C 7.1.1:
更改: 在 C++ 中,static 或 extern 修饰符只能用于对象或函数名。在 C++ 中,将这些修饰符与类型声明一起使用是非法的。在 C 中,当在类型声明上使用这些修饰符时会被忽略。例如:
static struct S { // valid C, invalid in C++ int i; };
解释:当与类型相关联时,存储类别说明符没有任何意义。在C++中,类的成员可以使用static存储类别说明符声明。允许在类型声明上使用存储类别说明符可能会使用户的代码变得混乱。
和
struct
一样,class
也是一个类型声明。通过在附录A中遍历语法树,可以得出相同的结论。
有趣的是,在C中,
static struct
是合法的,但没有效果:Why and when to use static structures in C programming?
C++中你想创建一个类的静态函数(而不是静态类)。
class BitParser {
public:
...
static ... getBitAt(...) {
}
};
你应该能够使用 BitParser::getBitAt() 调用函数,而无需实例化一个对象,这也是我假定的预期结果。
正如在这里所指出的,C++中实现此功能更好的方法可能是使用命名空间。但由于没有人在这里提到关键字final
,因此我会发布一个直接相当于C#中static class
的C++11或更高版本代码:
class BitParser final
{
public:
BitParser() = delete;
static bool GetBitAt(int buffer, int pos);
};
bool BitParser::GetBitAt(int buffer, int pos)
{
// your code
}
如前所述,您可以在C++中使用静态类。 静态类是没有实例化对象的类。 在C ++中,这可以通过将构造函数/析构函数声明为私有来实现。 最终结果是相同的。
public ref class BitParser abstract sealed
{
public:
static bool GetBitAt(...)
{
...
}
}
迟到总比不到好。