2009-08-27 4 views
0

J'utilise C++.Comment initialiser un membre statique en C++ à l'aide de la fonction

dans .h:

static CRITICAL_SECTION g_CS; 

dans .cpp:

CRITICAL_SECTION CQCommon::g_CS; 

mais je veux utiliser

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

dans une fonction statique. Comment puis-je appeler InitializeCriticalSection(PCRITICAL_SECTION pcs);?

Puis-je utiliser celui qui suit:

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

Et comment puis-je invoquer DeleteCriticalSection(&g_CS) après application quitter? En utilisant MFC, CCriticalSection semble être une solution.

+0

Mettre la g_CS déclaration de variable dans le fichier d'en-tête défaites dans le but de le rendre statique (à moins qu'il est un membre de classe statique) –

+0

Je suis désolé, je ne sais pas comprendre, pouvez-vous me donner un échantillon dans ma question? Je déclare toujours un membre statique de cette manière, cela semble fonctionner – user25749

+0

Les variables méritent d'être déclarées comme statiques, lorsqu'elles sont supposées être accessibles à partir d'une seule unité de compilation; vous mettez une déclaration de variable dans un fichier d'en-tête pour la raison inverse: lorsque vous voulez l'utiliser dans plusieurs unités de compilation. De même, mettre une déclaration dans un fichier d'en-tête sans le spécificateur extern aboutirait à des définitions en double pendant la liaison dès que deux unités de compilation incluront cet en-tête. –

Répondre

8

Si vous voulez une approche différente, vous pouvez créer un objet pour le gérer:

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

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

Cette sera maintenant géré automatiquement par C++. La section critique sera initialisée lors de la première saisie de la fonction et supprimée à la sortie du programme.

En outre, vous pouvez étendre en ayant la variable PCRITICAL_SECTION réelle à l'intérieur de la classe, etc .. etc ..

+5

Ce code est cassé. La norme C++ ne dit rien de la sécurité du thread de l'initialisation d'une variable statique dans une fonction et vous risquez de finir par initialiser man deux fois si deux threads exécutent simultanément Func. – Michael

1

Au point d'entrée à votre code - la fonction principale, appelez init:

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

    // do some stuff 

    DeleteCriticalSection(&g_CS); 

    // exit 
    return 0; 
} 
+0

C'est la meilleure façon de le faire - InitializeCriticalSection est très bon marché à appeler. – Michael

1

Eh bien, aujourd'hui la meilleure pratique consiste à utiliser modèle « scope de verrouillage » au lieu de EnterXXX et LeaveXX -comme les fonctions. Jetez un oeil à ce que boos a à offrir. Quoiqu'il en soit, une approche RAII peut vous aider ici:

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); 
    } 
} 
Questions connexes