Возможные дубликаты:
Где бы вы использовали функцию friend и статическую функцию?
С++: статические функции-члены
Когда целесообразно использовать статическую функцию-член в С++? Пожалуйста, дайте мне пример в реальном мире.
Возможные дубликаты:
Где бы вы использовали функцию friend и статическую функцию?
С++: статические функции-члены
Когда целесообразно использовать статическую функцию-член в С++? Пожалуйста, дайте мне пример в реальном мире.
Хорошее использование статических функций-членов:
Обратите внимание, что последний случай применяется к защищенной статической функции-члену, но не к частной. В последнем случае вы просто поместите его в блок компиляции класса, скрывая его как деталь реализации. Для защищенного, хотя вы хотите, чтобы он был видимым, хотя и ограниченным образом.
Типичный случай этого - "обманывать" отсутствие наследования дружбы.
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
}
Естественное место для использования - когда вы не можете использовать бесплатную функцию, потому что вам нужно получить доступ к внутренним функциям класса. Наиболее типичным примером этого является функция строителя, как показано ниже. Конструктор 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. Когда вам не нужно обращаться к защищенным и частным частям класса, статические функции-члены не нужны (могут использоваться свободные функции), но есть некоторые, которые используют статические функции-члены также, когда они находятся в домене класса, но не ограниченный/логический, чтобы использовать функцию в одном экземпляре.
Обычный пример, который вы найдете (в примере с реальным миром), - это когда вы создаете поток. API общей нити (POSIX/pthreads, Boost и Win32 CreateThread) требует отдельной подписи. Единственный способ получить эту подпись в функции-члене - это сделать функцию static.
Вы можете использовать функцию без экземпляра объекта. Также, если функция вызывается из другой статической функции, она должна быть статической.
Я неправильно прочитал ваш вопрос и ответил, когда ему нужно использовать статические функции.
Вы имели в виду статические функции-члены. здесь пример того, когда использовать статическую функцию-член - обернуть вызов потока внутри класса, чтобы ваш поток имел доступ к вашему классу...:
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;
}
Посмотрите шаблон дизайна, названный singleton. Короче говоря, это один из способов ограничить создание объекта. Таким образом, единственный способ создать объект - вызвать функцию члена С++, которая является статической.
Типичным примером может быть одиночный класс, в котором статический метод GetInstance() возвращает экземпляр singleton класса.
class Singleton
{
static Singleton instance;
private Singleton()
{
}
static Singleton & GetInstance()
{
if(instance == null)
instance = new Singleton();
return instance;
}
}