2009-04-29 33 views
0

代碼何時在C++類中使用關鍵字「static」?

static void MyClass::ThreadEntryStatic() 
{ 
    //... 
} 

void MyClass::Begin() 
{ 
     CreateThread(..,ThreadEntryStatic,..); 
} 

在這種條件下,我們應該使用靜態類?

+2

這是一個線程相關的問題或C++的問題? – Tom 2009-04-29 03:37:48

+3

這個問題的標題是誤導性的。增加與線程有關的事情可能會澄清事情。 – 2009-04-29 03:53:20

回答

4

有三個地方可以使用關鍵字static。一個是在聲明一個struct/class的時候,這個上下文意味着該方法是一個類方法而不是一個實例方法。這意味着這個方法是直接調用的,你不需要一個實例。從這個靜態方法中,你不能訪問實例變量。

在MyClass.h

struct MyClass 
{ 
    static void ThreadEntryStatic(); 

    void Begin(); 
}; 

在MyClass.cpp

void MyClass::ThreadEntryStatic() 
{ 
} 

void MyClass::Begin() 
{ 
    CreateThread(.., MyClass::ThreadEntryStatic, ...); 
} 

,其中靜態關鍵字的使用是一個文件,其中你不想能見度範圍第二種情況聲明在文件外部可見的變量。您也可以爲此使用匿名命名空間。

使用static關鍵字的第三種情況是在方法的範圍內,並且該值在函數的執行之間保留(並且在第一次使用賦值進行初始化時)。

1

如果您在多個線程上運行靜態方法,則需要非常注意同步代碼。在我看來,當進行多線程編程時,我嘗試在每個線程中使用單獨的對象或工作項的實例,並且完全避免使用任何類型的靜態或共享數據。當然,這並不總是可行的,所以線程仍然是最棘手的編程領域之一。

0

函數調用之間保留靜態變量的值。示例請查詢this MSDN條目。在chrish的回答中已經列出了定義和使用「靜態」方法的方法

實現單例類時需要只有一個類的實例時可以使用靜態。 它的使用取決於上下文。

1

舉一個具體的例子,

class Test{ 
     static void foo();  
}; 

static void Test::foo(){ 
    // code here 
} 

不會編譯,你是不是能夠聲明與static關鍵字的函數類的聲明之外。在實現該功能時,您只需刪除靜態關鍵字。

class Test{ 
     static void foo();  
}; 

void Test::foo(){ 
    // code here 
} 
1

有幾個人談到了這一點,但用於內部連接static不應該被使用,而應該使用匿名的命名空間:

namespace 
{ 

void myInternallyLinkedFunction() 
{ 
    // do something 
} 

int myInternallyLinkedInteger; 

class myInternallyLinkedClass 
{ 
public: 
    void doSomething(); 
}; 

} // anon namespace 


void myExternallyLinkedFunction() 
{ 

    ++myInternallyLinkedInteger; 
    myInternallyLinkedFunction(); 
    myInternallyLinkedClass x; 
    x.doSomething(); 
} 
0

你的例子顯示的是一個「靜態成員函數線程回調「模式。由於線程函數必須具有WINAPI簽名,因此它不能是普通的成員函數,只能是靜態成員。通常你將這個作爲線程參數傳遞給這個回調函數,然後調用一個真正的成員來執行線程工作。

靜態成員只有一種用法,並且有許多不同之處。真的很難猜出你的問題的目的是什麼。你正在解決一些特定的問題,還是隻關心靜態成員或靜態成員函數的所有可能用法?

「靜態成員函數線程回調」的更完整的例子:

class MyClass 
{ 

    /// background rendering thread 
    int ThreadEntry() 
    { 
    // do the work here 
    } 

    /// static member callback "proxy" 
    static DWORD WINAPI ThreadEntryStatic(void *param) 
    { 
    return ((EngineDD9 *)param)->ThreadEntry(); 
    } 

    void SpawnThread() 
    { 
    CreateThread(.., ThreadEntryStatic, ...); 
    } 

};