Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meyers Singleton Scope

In the following program, it seems like the Registry Singleton isn't being persisted across calls to the static functions. What is the problem with this approach?

#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;
}
like image 217
agg212 Avatar asked Apr 07 '26 00:04

agg212


2 Answers

You are correctly returning a reference to your singleton, but when you use it you are taking a copy. Offending line follows:

Registry reg = Test::registry();

To fix the problem, modify this to:

Registry & reg = Test::registry();

To prevent this from ever happening, you can prevent the compiler from allowing copies by deleting the copy constructor and assignment operators:

class Registry : public unordered_map<string,string>
{
    public:
        Registry() {}
        Registry( const Registry & ) = delete;
        Registry & operator=( const Registry & ) = delete;
};
like image 97
paddy Avatar answered Apr 09 '26 13:04

paddy


Your code makes a copy of the registry in each function call and then throws the copy away.

Instead, you want to make a reference to the one and only registry:

Registry & reg = Test::registry();
//      ^^^
like image 35
Kerrek SB Avatar answered Apr 09 '26 12:04

Kerrek SB