Ответ 1

Хорошее использование статических функций-членов:

  • Мета-программирование. Реальный пример - шаблон std:: char_traits. Все функции-члены статичны.
  • Создание его статической функции-члена дает ему доступ к закрытым членам класса, хотя и здесь будет достаточно другого друга
  • Защищенная статическая функция-член, таким образом, доступна только для класса и классов, полученных из него.

Обратите внимание, что последний случай применяется к защищенной статической функции-члену, но не к частной. В последнем случае вы просто поместите его в блок компиляции класса, скрывая его как деталь реализации. Для защищенного, хотя вы хотите, чтобы он был видимым, хотя и ограниченным образом.

Типичный случай этого - "обманывать" отсутствие наследования дружбы.

class B
{
   friend class A;
   // lots of private stuff
};

class A
{
protected:
   static void callsSomePrivateMembers( B& b );
};

class AChild : public A
{
   void foo( B& b );
}

void AChild::foo( B& b )
{
      // AChild does not have private access to B as friendship is not inherited
      // but I do have access to protected members of A including the static ones

    callsSomePrivateMembers( b ); // get to call them through a back-door
}

Ответ 2

Естественное место для использования - когда вы не можете использовать бесплатную функцию, потому что вам нужно получить доступ к внутренним функциям класса. Наиболее типичным примером этого является функция строителя, как показано ниже. Конструктор Foo является конфиденциальным, чтобы убедиться, что он не сконструирован каким-либо другим способом, кроме функции-строителя.

#include <iostream>

class Foo {
public:
  static Foo* createFoo() {return new Foo();}
private: 
  Foo() {}
};

int main() {
  //Foo nonBuiltFoo; //wont compile
  Foo* freshFoo = Foo::createFoo();
  delete freshFoo;
  return 0;
}

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

Ответ 3

Обычный пример, который вы найдете (в примере с реальным миром), - это когда вы создаете поток. API общей нити (POSIX/pthreads, Boost и Win32 CreateThread) требует отдельной подписи. Единственный способ получить эту подпись в функции-члене - это сделать функцию static.

Ответ 4

Вы можете использовать функцию без экземпляра объекта. Также, если функция вызывается из другой статической функции, она должна быть статической.

Ответ 5

Я неправильно прочитал ваш вопрос и ответил, когда ему нужно использовать статические функции.

Вы имели в виду статические функции-члены. здесь пример того, когда использовать статическую функцию-член - обернуть вызов потока внутри класса, чтобы ваш поток имел доступ к вашему классу...:

static unsigned WINAPI ArchiveAgent::LogMsgPump(PVOID pData)
{
    ArchiveAgent* pSmith = reinterpret_cast<ArchiveAgent*>(pData);

    if( pSmith )
        pSmith->LogMsgPump();
    else
        return -1;

    return 0;
}

unsigned WINAPI ArchiveAgent::LogMsgPump()
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    // ....

    CoUninitialize();
    return 0;
}

Вот мой ответ на простые старые статические функции. Я использую статические функции, когда нет смысла, чтобы эта функция принадлежала классу.

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

static HRESULT CreateFolder( CString & sPath )
{
// create the destination folder if it doesn't already exist

HRESULT hr      = S_OK;
DWORD   dwError = 0;

if( sPath.GetLength() == 0 || sPath.GetLength() < 2 )                   
    return E_UNEXPECTED;

if( GetFileAttributes( (LPCWSTR) sPath ) == INVALID_FILE_ATTRIBUTES )
{           
    dwError = SHCreateDirectoryEx(NULL, (LPCWSTR)sPath, NULL);

    if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_EXISTS && dwError != ERROR_ALREADY_EXISTS)
        hr = HRESULT_FROM_WIN32(dwError);
}

return hr;

}

Ответ 6

Посмотрите шаблон дизайна, названный singleton. Короче говоря, это один из способов ограничить создание объекта. Таким образом, единственный способ создать объект - вызвать функцию члена С++, которая является статической.

Ответ 7

Типичным примером может быть одиночный класс, в котором статический метод GetInstance() возвращает экземпляр singleton класса.

class Singleton
{
    static Singleton instance;

    private Singleton()
    {
    }

    static Singleton & GetInstance()
    {
      if(instance == null)
        instance = new Singleton();

      return instance;
    }
}