2015-12-09 56 views
2

在下面的程序中,似乎註冊表單例不會在對靜態函數的調用中持久化。這種方法有什麼問題?Meyers Singleton Scope

#include <iostream> 
#include <string> 
#include <unordered_map> 

using namespace std; 

class Test { 
typedef unordered_map<string,string> Registry; 
public: 
    static Registry &registry() { 
     static Registry reg; 
     return reg; 
    } 

    static void put(string key, string val) { 
     Registry reg = Test::registry(); 
     reg[key] = val; 
    } 

    static string get(string key) { 
     Registry reg = Test::registry(); 
     return reg[key]; 
    } 
}; 

int main() { 
    Test::put("a", "apple"); 
    Test::put("b", "banana"); 
    cout << Test::get("a") << endl; 
    cout << Test::get("b") << endl; 
    return 0; 
} 

回答

3

您正確地返回到你的單身參考,但是當你使用它,你正在服用的副本。問題的行如下:

Registry reg = Test::registry(); 

要解決此問題,修改此來:

Registry & reg = Test::registry(); 

爲了防止這種情況不斷髮生,你可以通過刪除拷貝構造函數和賦值運算符防止編譯器允許拷貝:

class Registry : public unordered_map<string,string> 
{ 
    public: 
     Registry() {} 
     Registry(const Registry &) = delete; 
     Registry & operator=(const Registry &) = delete; 
}; 
2

您的代碼會在每個函數調用中生成一個註冊表的副本,然後拋出該副本。

相反,你想一個參考的唯一註冊表:

Registry & reg = Test::registry(); 
//  ^^^