私有静态成员函数有什么用?

发布于 2024-11-16 20:40:52 字数 800 浏览 4 评论 0原文

我正在查看 请求解析器 boost::asio 示例,我想知道为什么像 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()。那么这些函数是静态的有什么原因吗?

I was looking at the request parser from the boost::asio example and I was wondering why the private member functions like is_char() are static? :

class request_parser
{
  ...
  private:
    static bool is_char(int c);
  ...
};

It is used in the function consume which is not a static function:

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;
    }
    ...

Only member functions can call is_char() and no static member function is calling is_char(). So is there a reason why these functions are static?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

终止放荡 2024-11-23 20:40:52

这个函数可以很容易地成为独立的,因为它不需要类的对象来操作。使函数成为类的静态成员而不是自由函数有两个优点:

  1. 如果对象是静态的或传递给函数,则它使函数可以访问该类的任何对象的私有和受保护成员;
  2. 它以类似于命名空间的方式将函数与类关联起来。

在这种情况下,似乎只适用第二点。

This function could easily have been made freestanding, since it doesn't require an object of the class to operate within. Making a function a static member of a class rather than a free function gives two advantages:

  1. It gives the function access to private and protected members of any object of the class, if the object is static or is passed to the function;
  2. It associates the function with the class in a similar way to a namespace.

In this case it appears only the second point applies.

寻找一个思念的角度 2024-11-23 20:40:52

那么这些函数是静态的有什么原因吗?

静态成员函数有一个隐藏的附加参数,称为this。传递此参数并不是免费的,因此创建私有函数静态可以被视为优化.
但它也可以被视为在代码中表达您的需求/设计的一种手段:如果该函数不需要引用该类的任何成员数据,为什么它应该是一个非静态成员函数?

但是,更改任何成员函数的类型(publicprivatestatic 与否)都将要求所有客户端重新编译。如果需要对那些客户端永远无法使用的私有函数执行此操作,那就是资源浪费。因此,我通常将尽可能多的函数从类的私有部分移至实现文件中的未命名命名空间

So is there a reason why these functions are static?

Non-static member functions have a hidden additional parameter called this. Passing this doesn't come for free, so making a private function static can be seen as a means of optimization.
But it can also be seen as a means of expressing your requirements/design in your code: If that function doesn't need to refer to any member data of the class, why should it be a non-static member function?

However, changing the type of any member function, public or private, static or not, will require all clients to recompile. If this needs to be done for a private function which those clients can never use, that's a waste of resources. Therefore, I usually move as many functions as possible from the class' private parts into an unnamed namespace in the implementation file.

围归者 2024-11-23 20:40:52

对于这个具体示例,static is_char() 的选择很可能是文档选择。其目的是让您印象深刻,is_char() 方法并不局限于类的特定实例,但功能特定于类本身

换句话说,通过使其静态,他们说is_char()是一种实用函数……无论给定的状态如何都可以使用它。实例。通过将其设为私有,他们表示您(作为客户)不应尝试使用它。它要么没有按照你想象的那样做,要么是以一种非常受限、受控的方式实现的。

@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();
}
...

For this specific example, the choice for a static is_char() is most likely a documentation one. The intent is to impress upon you that the is_char() method is not contrained to a specific instance of the class, but the functionality is specific to the class itself.

In other words, by making it static they are saying that is_char() is a utility function of sorts...one which can be used irrespective of the state of a given instance. By making it private, they are saying that you (as a client) should not try to use it. It either does not do what you think it does, or is implemented in a very constrained, controlled way.

@Mark Ransom's answer brings up a good point for the practical use of a private static member function. Specifically, that member function has access to private and protected members of either a static object or a passed instance of an instantiated object.

One common application of this is to abstract a pthread implementation in somewhat of an object oriented way. Your thread function must be static, but declaring it private limits the accessibility of that function to the class (to all but the most determined). The thread can be passed an instance of the class it's being "hidden" in, and now has access to perform logic using the object's member data.

Simplistic Example:

[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();
}
...
南风几经秋 2024-11-23 20:40:52

它是静态的,因为它不需要访问 request_parser 对象的任何成员变量。因此,使其静态可以使函数解耦,因为它减少了函数可以访问的状态量。

无论如何,如果这个函数根本不是 request_parser 类的一部分,那就更好了 - 相反,它应该是(可能在命名空间中)request_parser 类中的一个自由函数。代码>.cpp 文件。

It's static, since it doesn't require access to any member variables of request_parser objects. Hence, making it static decouples the function since it reduces the amount of state which the function can access.

For what it's worth, it would have been even better if this function wasn't part of the request_parser class at all - instead, it should have been (possibly in a namespace) a free function in the .cpp file.

浴红衣 2024-11-23 20:40:52

重点不在于在哪里使用它。问题是它使用什么。。如果它的定义不使用任何非静态成员,我会将函数设为静态,根据相同的原则,我不会将冗余参数传递给任何函数(除非它们要在重载结果中使用)

The point isn't where it is used. The question is what it uses. If its definition doesn't use any nonstatic members, I would make the function static, according to the same principle that I wouldn't pass a redundant parameter to any function (unless they were to be used in overload resulion)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文