可能顯示的文件:
Where would you use a friend function vs a static function?
C++: static member functions何時使用靜態成員函數?
時候適合使用C++中的靜態成員函數?請給我一個真實世界的例子。
可能顯示的文件:
Where would you use a friend function vs a static function?
C++: static member functions何時使用靜態成員函數?
時候適合使用C++中的靜態成員函數?請給我一個真實世界的例子。
好用途:
請注意,最後一種情況適用於受保護的靜態成員函數,但不適用於私有函數。在後一種情況下,您只需將其放入該類的編譯單元中,作爲實現細節隱藏起來。對於受保護的人來說,儘管你希望它是可見的,儘管受到限制。
一個典型的案例是「欺騙」缺乏友誼的繼承。
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
}
一個常見的例子,你會發現(在現實世界的例子)是當你創建一個線程。公共線程API(POSIX/pthreads,Boost和Win32 CreateThread)都需要特定的簽名。在成員函數中獲得簽名的唯一方法是使函數靜態。
自由功能可以很好地工作。 – 2011-02-07 12:42:13
我誤解了你的問題,並回答了何時適合使用靜態函數。
你的意思是靜態成員函數。這裏的時候使用一個靜態成員函數的例子 - 包裝一個線程調用一個類裏面,讓你的線程可以訪問你的類...:
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的設計模式。簡而言之,它是限制對象創建的一種方法。因此,創建對象的唯一方法是調用靜態的C++成員函數。
一個典型的例子可以是一個單例類,其中靜態GetInstance()方法返回該類的單例實例。靜態成員函數
class Singleton
{
static Singleton instance;
private Singleton()
{
}
static Singleton & GetInstance()
{
if(instance == null)
instance = new Singleton();
return instance;
}
}
使用它的自然地方是當你不能使用免費函數,因爲你需要訪問該類的內部。這個最典型的例子是一個構建器函數,如下所示。 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模式。當你不必訪問類的受保護和私有部分時,靜態成員函數不是必需的(可以使用自由函數),但是有一些靜態成員函數也在類的域內時使用靜態成員函數限制/邏輯在單個實例上使用該功能。
什麼是'oops`標籤? – Maxpm 2011-02-07 12:16:20
我編輯的問題,因爲我認爲作者只是意味着「面向對象」,或面向對象的編程。 – 2011-02-07 12:18:35
http://stackoverflow.com/questions/4723143/c-static-member-functions – Mahesh 2011-02-07 12:20:25