0

Ich habe einige Objekte als global definiert, was bedeutet, dass ihr Konstruktor vor dem Programmstart oder unter DllMain() eingegeben werden. Dies verursacht einige Probleme, und deshalb möchte ich sie zu lokalen statischen verschieben.C++ 11 Magic Statik Workaround in Visual Studio 2012

Unser Hauptprojekt sind hauptsächlich unter Visual Studio 2012. Nach diesen Posts.

The Magic Statiken ist nicht in Visual Studio 2012 (bis VS 2015) umgesetzt. Daher ist die Initialisierung der lokalen statischen Variablen nicht automatisch vor dem gleichzeitigen Zugriff durch den Compiler geschützt.

Was ist eine geeignete Problemumgehung oder Lösung für diesen Fall?


Hier ist, was ich versucht:

eine Sperre hinzufügen zu schützen. Aber wenn die Variable initialisiert wird, bevor die Funktion eingegeben wird, kann mein Schloss unbrauchbar sein ...

// data object 
struct Cat 
{ 
    Cat() 
    { 
     std::cout << __FUNCTION__ << "\n"; 
    } 
}; 

// lock mutex for singleton getter 
static std::mutex getcat_m; 

// singleton getter 
Cat& GetCat(){ 
    std::cout << __FUNCTION__ << " In\n"; 

    std::lock_guard<std::mutex> lk(getcat_m); 
    static Cat cat; 

    std::cout << __FUNCTION__ << " Out\n"; 
    return cat; 
} 

int main(int argc, char* argv[]) 
{ 
    std::cout << __FUNCTION__ << " In\n"; 
    Cat& cat = GetCat(); 
    std::cout << __FUNCTION__ << " Out\n"; 

    std::cin.ignore(); 
    return 0; 
} 

Es zeigt tatsächlich wie erwartet. Der Konstruktor wird aufgerufen, nachdem die Funktion eingegeben wurde.

main In 
GetCat In 
Cat::Cat 
GetCat Out 
main Out 

Aber ich bin mir nicht sicher, ob dies eine geeignete Lösung ist.

+1

Sie können auch 'std :: call_once' ausprobieren. Sieht so aus, als wäre es auch empfehlenswert [18.2.4 Verwenden Sie std :: call_once anstelle des Double-Checked Locking-Patterns] (http://www.codingstandard.com/rule/18-2-4-use-stdcall_once-rather-than- das-doppelt-geprüfte-Sperrmuster /) –

Antwort

0

Dank A. A im Kommentar für den Link 18.2.4 Use std::call_once rather than the Double-Checked Locking pattern.

Ich habe das Beispiel aus der Guildline referenziert und schreibe meinen Singleton-Getter-Code wie folgt um.

// Cat.cpp 
static std::once_flag once_Cat; 
static Cat* gpCat = nullptr; 
void init_Cat() { gpCat = new Cat(); } 

Cat& GetCat() { 
    std::call_once(once_Cat, init_Cat); 
    return *gpCat; 
}