-1

I wish to create a static Class object which should stay in the memory while the program is running. The object needs to be initialized only once by the init function and the output function will be called in a static method always. Does my code make sense and is it thread-safe?

class Singleton
{
public: 
       static void init(const int value)
       {
              static Singleton inst;
              inst.Value = value;
       }
       static int prnValue()
       {
               return Value;
       }

private:
       Singleton() {};
       static int Value;
};

int main()
{
       int inputValue = 10;

       Singleton::init(inputValue);
       cout << Singleton::prnValue();

       return 0;
}

New Edit: Or can I try like this then?

class Singleton
{
public: 
       static Singleton& init(const int value)
       {
              static Singleton inst;
              inst.Value = value;

              return inst;
       }
       static int prnValue()
       {
               return Value;
       }

private:
       Singleton() {};
       static int Value;
};

Addition: Meyer's singleton example look like

class Singleton
{
public: 
       static Singleton& init()
       {
              static Singleton inst;

              return inst;
       }

private:
       Singleton() {};
};

So Isn't my code consistent with Meyer's example?

Try4: How about this?

class Singleton
{
public: 
       static Singleton& init(int value)
       {
              static Singleton inst(value);
              return inst;
       }
       static int prnValue()
       {
               return Value;
       }
private:
       Singleton(value) 
       {
              Value = value;
       }
       int Value;
};

Added comment: How to pass argument in a singleton seems to provide the same answer as Try4.

user12275660
  • 3
  • 1
  • 3
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/201433/discussion-on-question-by-user12275660-beginners-c-thread-safe-singleton-desi). – Samuel Liew Oct 25 '19 at 21:37
  • In a multithreading context (not sure from the text of your question), you can protect the initialization using the classic [std::call_once](https://en.cppreference.com/w/cpp/thread/call_once) library function. The clue is in the name. – jpmarinier Oct 25 '19 at 21:43

1 Answers1

0

Abandon Singleton and make Value a const global variable initialized with a helper function.

Example:

// anonymous namespace to bind the global to this file to prevent the static 
// initialization order fiasco
namespace 
{
    const int Value = ReadIniFile("section", "key", default_value);
}

But what if you need to use this variable in other files? The best advice I've got is don't. But if you must, the static initialization order fiasco needs to be overcome. Here's a quick way to do that that is similar to what you've seen so far:

// Lazy loader function similar to Meyers Singleton
int Value()
{
    static int value = ReadIniFile("section", "key", default_value);
    return value;
}

Usage:

me_function_need_Value(Value());

This ensures that Value is initialized before anyone can try to use it no matter which file in your project needs it. Unfortunately it's now hard to figure out when it goes out of scope, so the problem doesn't really go away. It's just moved from the start of the program to the end where it is a little more manageable. See Destruction order of static objects in C++ . Ensure no one uses Value after main exits and you'll be safe. Still, use with caution.

user4581301
  • 33,082
  • 7
  • 33
  • 54