2009-08-27 103 views
0

我正在使用C++。如何在C++中使用函數初始化靜態成員

.h

static CRITICAL_SECTION g_CS; 

.cpp

CRITICAL_SECTION CQCommon::g_CS; 

,但我想在一個靜態函數使用

QGUID temp; 
EnterCriticalSection(&g_CS); 
temp = g_GUID++; 
LeaveCriticalSection(&g_CS); 
return temp; 

。 如何調用InitializeCriticalSection(PCRITICAL_SECTION pcs);

我可以使用下面的一個:

QGUID func(XXX) 
{ 
    static { 
    InitializeCriticalSection(&g_CS); 
    } 
        QGUID temp; 
        EnterCriticalSection(&g_CS); 
        temp = g_GUID++; 
        LeaveCriticalSection(&g_CS); 
        return temp; 
} 

我怎樣才能應用後調用DeleteCriticalSection(&g_CS)離開?

使用MFC,看起來CCriticalSection是一個解決方案。

+0

把g_CS在頭文件中的變量聲明擊敗作出的目的,靜態的(除非它是一個靜態類成員) – 2009-08-27 02:04:15

+0

我很抱歉,我不明白,你能給我一個樣本在我的問題? 我總是用這種方式聲明靜態成員,看來工作 – user25749 2009-08-27 02:21:24

+0

當應該只從一個編譯單元訪問變量時,變量值得聲明爲靜態的;您將一個變量聲明放在頭文件中的原因相反:當您想在多個編譯單元中使用它時。另外,在沒有extern說明符的情況下將聲明放入頭文件時,只要兩個編譯單元包含該頭文件,就會在鏈接期間導致重複的定義。 – 2009-08-27 02:28:35

回答

8

如果你想有一個不同的方法,您可以創建一個對象來管理它:

class CriticalSectionManager 
{ 
    public: 
    CriticalSectionManager() 
    { 
    InitializeCriticalSection(&g_CS); 
    } 
    ~CriticalSectionManager() 
    { 
    DeleteCriticalSection(&g_CS); 
    } 
}; 

void Func(void) 
{ 
    static CriticalSectionManager man; 
    //Do stuff 
} 

這現在將由C++自動管理。關鍵部分將在函數初次輸入時初始化,並在程序退出時刪除。

而且可以通過具有類內部的實際PCRITICAL_SECTION變量等。等擴展這個..

+5

此代碼已損壞。 C++標準沒有提到函數內部靜態變量初始化的線程安全性,如果兩個線程同時執行Func,你可能會初始化人兩次。 – Michael 2009-08-27 22:00:09

1

在入口點代碼 - 主函數,調用init:

int main(...) 
{ 
    InitializeCriticalSection(&g_CS); 

    // do some stuff 

    DeleteCriticalSection(&g_CS); 

    // exit 
    return 0; 
} 
+0

這是執行此操作的最佳方式 - InitializeCriticalSection調用起來非常便宜。 – Michael 2009-08-27 01:42:09

1

好了,今天最好的做法是使用「作用域鎖」模式,而不是EnterXXX和LeaveXX樣功能。看看噓聲有什麼提供。 無論如何,一個RAII方法可以幫助你在這裏:

class MyCriticalSection 
{ 
private: 
    CRITICAL_SECTION m_CS; 
public: 
    MyCriticalSection() 
    { 
    ::InitializeCriticalSection(&m_CS); 
    } 
    ~MyCriticalSection() 
    { 
    ::DeleteCriticalSection(&m_CS); 
    } 
    void Lock() 
    { 
    ::EnterCriticalSection(&m_CS); 
    } 
    void UnLock() 
    { 
    ::LeaveCriticalSetion(&m_CS); 
    } 
}