2009-08-27 118 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); 
    } 
}