我正在查看boost :: asio示例中的request parser,我想知道为什么像is_char()
这样的私有成员函数是static
? :
class request_parser
{
...
private:
static bool is_char(int c);
...
};
它在函数consume中使用,它不是静态函数:
boost::tribool request_parser::consume(request& req, char input)
{
switch (state_)
{
case method_start:
if (!is_char(input) || is_ctl(input) || is_tspecial(input))
{
return false;
}
...
只有成员函数可以调用is_char()
,并且没有静态成员函数正在调用is_char()
。那么为什么这些函数是静态的呢?
答案 0 :(得分:61)
这个功能可以很容易地实现独立,因为它不需要类的对象在其中运行。使函数成为类的静态成员而不是自由函数有两个好处:
在这种情况下,只显示第二点。
答案 1 :(得分:15)
那么为什么这些函数是静态的呢?
非static
成员函数有一个名为this
的隐藏附加参数。传递此信息并非免费,因此将private
函数static
视为 优化 的一种方式。
但它也可以被视为 在您的代码中表达您的需求/设计 的一种方式:如果该函数不需要引用该类的任何成员数据,为什么它应该是非static
成员函数?
但是,更改任何成员函数的类型public
或private
,static
是否需要重新编译。如果需要为这些客户端永远不能使用的private
函数执行此操作,则会浪费资源。因此,我通常会将类的私有部分中的尽可能多的函数移动到实现文件 中的 未命名的命名空间中。
答案 2 :(得分:5)
对于此特定示例,static is_char()
的选择很可能是文档编制。目的是向您强调is_char()
方法不限于类的特定实例,但功能特定于类本身。
换句话说,通过使它成为static
,他们说is_char()
是各种各样的效用函数......无论给定实例的状态如何,都可以使用它。通过制作private
,他们说你(作为客户)不应该尝试使用它。它要么不按照你的想法做,要么以非常有限的受控方式实施。
@Mark Ransom的回答为实际使用私有静态成员函数提出了一个很好的观点。具体来说,该成员函数可以访问静态对象或实例化对象的传递实例的私有成员和受保护成员。
这个的一个常见应用是以某种面向对象的方式抽象pthread实现。您的线程函数必须是静态的,但声明它是私有的限制了该函数对类的可访问性(除了最确定的所有函数)。线程可以传递给它“隐藏”的类的实例,现在可以使用对象的成员数据来执行逻辑。
简单示例:
[MyWorkerClass.h]
...
public:
bool createThread();
private:
int getThisObjectsData();
pthread_t myThreadId_;
static void* myThread( void *arg );
...
[MyWorkerClass.cpp]
...
bool MyWorkerClass::createThread()
{
...
int result = pthread_create(myThreadId_,
NULL,
myThread),
this);
...
}
/*static*/ void* MyWorkerClass::myThread( void *arg )
{
MyWorkerClass* thisObj = (MyWorkerClass*)(arg);
int someData = thisObj->getThisObjectsData();
}
...
答案 3 :(得分:2)
它是静态的,因为它不需要访问request_parser
个对象的任何成员变量。因此,使其静态解耦函数,因为它减少了函数可以访问的状态量。
对于它的价值,如果这个函数根本不是request_parser
类的一部分会更好 - 相反,它应该(可能在命名空间中)是{中的自由函数{1}}档案。
答案 4 :(得分:0)
这一点不是 使用 。问题是 它使用的 。如果它的定义不使用任何非静态成员,我将使函数静态,根据我不会将冗余参数传递给任何函数的相同原则(除非它们用于过载结果)