Подтвердить что ты не робот

Что такое использование частных статических функций-членов?

Я смотрел на синтаксический анализатор из примера boost:: asio, и мне было интересно, почему частный член работает как is_char() static?

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

Используется в функции потреблять, которая не является статической функцией:

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(). Итак, есть ли причина, почему эти функции являются статическими?

4b9b3361

Ответ 1

Эта функция легко могла быть сделана автономной, поскольку она не требует, чтобы объект класса работал внутри. Создание функции статический член класса, а не свободная функция дает два преимущества:

  • Он предоставляет функции доступ к закрытым и защищенным членам любого объекта класса, если объект статичен или передан функции;
  • Он сопоставляет функцию с классом аналогично пространству имен.

В этом случае появляется только вторая точка.

Ответ 2

Итак, есть ли причина, почему эти функции являются статическими?

Не-static функции-члены имеют скрытый дополнительный параметр this. Передача этого происходит не бесплатно, поэтому создание private функции static можно рассматривать как средство оптимизации.
Но это также можно рассматривать как средство , выражающего ваши требования/дизайн в вашем коде. Если этой функции не нужно ссылаться на какие-либо данные члена класса, почему это должно быть не- static функция-член?

Однако изменение типа любой функции-члена, public или private, static или нет, потребует повторной компиляции всех клиентов. Если это нужно сделать для функции private, которую эти клиенты никогда не могут использовать, это пустая трата ресурсов. Поэтому я обычно перемещаю как можно больше функций из частных частей класса в неназванное пространство имен в файле реализации.

Ответ 3

В этом конкретном примере выбор для 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();
}
...

Ответ 4

Он статический, так как он не требует доступа к любым переменным-членам объектов request_parser. Следовательно, это делает ее статической развязывает функцию, поскольку она уменьшает количество состояний, к которым может обращаться функция.

Для чего было бы лучше, если бы эта функция вообще не была частью класса request_parser - вместо этого она должна была быть (возможно, в пространстве имен) свободной функцией в .cpp файл.

Ответ 5

Точка не , где используется. Вопрос: какой он использует. Если его определение не использует каких-либо нестатических членов, я бы сделал функцию static, согласно тому же принципу, что я бы не передавал избыточный параметр какой-либо функции (если бы они не использовались при перегрузке)